| 

.NET C# Java Javascript Exception

5
Hallo,
ich möchte mir eine eigene Klasse erstellen die eine Funktion enthalten soll, bei der ich einen Parameter übergeben kann. Dieser Parameter soll aber nicht willkürlich ausgewählt werden können, sondern soll 2 vorgegebene Werte Enthalten dürfen- aber eben kein boolean, sie soll als String deklariert sein. also praktisch :
cControl.Aktion(hier als Auswahl "Start" und "Stop")
Ich habe schon einige Zeit danach, kenne aber den genauen Begriff, von dem was ich möchte nicht- ich denke daher habe ich bislang einfach noch nicht das passende gefunden.

Ich hoffe Ihr könnt mir weiterhelfen.
Danke und Gruß
Patrick
20.03.2014
P4trick 31 3
4 Antworten
2
Du meinst vermutlich die Enumeration, den Du definieren kannst:

Public Enum Action
Start
Stop
End Enum


siehe auch hier: http://msdn.microsoft.com/de-de/library/8h84wky1.aspx
20.03.2014
Roland Bär 335 6
2
@P4trick:
Was ist der Sinn einer Methode Aktion(Enum)? Wenn ich Start() und Stop() aufrufen möchte, dann nenne ich meine Methoden éinfach so. Explizitheit ist keinesfalls etwas Schlechtes. Da ich Deinen UseCase nicht kenne, kann ich Dir aber weder von Deinem Vorgehen abraten noch etwas anderes empfehlen.

Dass das Enum in C# eklatante Schwächen hat, hat bei mir dazu geführt, dass ich es äußerst selten und nur unter genau definierten Umständen einsetze. Das Problem der nicht definierten Werte wurde ja schon angesprochen, das ist das Eine. Viel schlimmer finde ich die Tatsache, dass heutzutage leichtsinnig Enums implementiert werden, an deren Wert konkretes Verhalten geknüpft ist. Die Konsequenz davon sind hässliche switch-Statements wild verstreut in der Codebase, um abh. vom konkreten Enumwert ein konkretes Verhalten auszuführen. OCP ade! Die Lösung für derartige Probleme bringt die Sprache Gott sei Dank selbst mit, sie heißt Polymorphie. Wann auch immer an einen Enum Verhalten geknüpft wird, ist es kein Enum, sondern ein polymorpher Typ. Als Nutzer eines solchen Typs muss man sich auch nicht umgewöhnen, aber man wird das switch-Statement los und kann auf dem "Enum" eine Methode aufrufen, statt zu verzweigen.

Beispiel:
public enum EmployeeType
{
Boss,
Other
}

public bool GetsBigBonusAtEndOfYear(EmployeeType e)
{
switch(e)
{
case Boss:
return true;
case Other:
return false;
default:
return false;
}
}

public abstract class EmployeeType
{
public abstract bool IsEligibleForBonus();

private class BossType : EmployeeType
{
public override bool IsEligibleForBonus()
{
return true;
}
}

private class OtherType : EmployeeType
{
public override bool IsEligibleForBonus()
{
return false;
}
}

public static readonly EmployeeType Boss = new BossType();
public static readonly EmployeeType Other = new OtherType();
}

// neue Variante, macht die Methode eigtl. überflüssig
public bool GetsBigBonusAtEndOfYear(EmployeeType e)
{
return e.IsEligibleForBonus();
}


Zugegeben, das Beispiel ist ein wenig konstruiert und sehr einfach gehalten, aber ich denke es verdeutlicht ganz gut was ich sagen möchte.
Mein Fazit:
Sobald ein Enum Verhalten steuert (das merkt man eigentlich sofort am ersten switch, den man dafür schreibt), sollte man kurz über eine andere Technik der Implementierung nachdenken. Verstreute switch-Statements über ein Enum führen beim Hinzufügen eines neuen Werts in die Enumeration unweigerlich zu Shotgun Surgery. Das muss nicht sein.
22.03.2014
ffordermaier 8,4k 3 9
1
Nur als Antwort gepostet, damit der Code lesbar ist. (Fortsetzung des Kommentars auf die Antwort: "genau das wars, danke dir :-)"

class Program
{
enum ControlActions
{
Start,
Stop
}

static void ExecuteAction(ControlActions action)
{
switch (action)
{
case ControlActions.Start:
Console.WriteLine("Starting ...");
break;
case ControlActions.Stop:
Console.WriteLine("Stopping ...");
break;
default:
Console.WriteLine("Upps ??? value: {0}, isDefined: {1}",
action.ToString(),
Enum.IsDefined(typeof(ControlActions), action));
break;
}
}
static void Main(string[] args)
{
ExecuteAction(ControlActions.Start);
string theAnswer = "42";
var theAction = (ControlActions)Enum.Parse(typeof(ControlActions), theAnswer);
ExecuteAction(theAction);
ExecuteAction(ControlActions.Stop);
Console.ReadLine();
}
}


Ausgabe:
Starting ...
Upps ??? value: 42, isDefined: False
Stopping ...


Was ich damit nur sagen möchte: Man darf sich nicht einfach blind auf Enum - Werte verlassen ... ;)

Ciao,
Mike
21.03.2014
Xantiva 2,3k 2 9
0
genau das wars, danke dir :-)
21.03.2014
P4trick 31 3
Danke für Deine Rückmeldung.
Mit klicken auf den Haken bei meiner Antwort kannst Du in diesem Fall die Frage als beantwortet markieren.
Und Deine Rückmeldung wäre als Kommentar bei meiner Antwort besser platziert gewesen :-)
Roland Bär 21.03.2014
Wobei noch anzumerken wäre, dass man in diesem Fall auch so etwas wie 42 übergeben kann, da Start und Stop eigentlich ein Integer sind.
Tosch 21.03.2014
@Tosch: Ja, dies ist eine Unschönheit bei VB.NET. Dasselbe in C# wird vom Compiler abgefangen, wenn Du keinen expliciten Cast machst.
Roland Bär 21.03.2014
1
Dann sollte man Parameter prüfen:

If Not ([Enum].IsDefined(GetType(Action), value)) Then
Throw New Exception("aktion")
End If
lbm1305 21.03.2014
Die Variante, dass dies der Compiler prüft, gefällt mir trotzdem besser... :-)
Roland Bär 21.03.2014
1
@lbm1305: man lernt doch jeden Tag wieder was Neues.
Tosch 21.03.2014
Hm, was fängt der Compiler da ab? Auch wenn der Übergabeparameter ein Enum ist, kann ich da problemlos "Unsinn" hineinreichen! Das Enum.Isdefinded ist die einzig sichere Lösung.
Ich könnte per Enum.Parse ihm die 42 reinreichen und der Code hätte ein Problem ;)
Xantiva 21.03.2014
Hmpf, Kommentare editieren wäre schon, um seine peinlichen Tippfehler zu korrigieren :(
=> IsDefined
Xantiva 21.03.2014
@Xantiva: Bei C# fängt der Compiler ab, wenn Du einen int anstelle eines enums übergibst (ohne cast). Darauf bezog ich mich beim Kommentar "Die Variante, dass dies der Compiler prüft, gefällt mir trotzdem besser..."
Dies ist aber leider bei VB.NET meines Wissens nicht möglich.
Roland Bär 21.03.2014
Ja, wenn ich einen int übergebe. Aber ich kann auch ein Enum Wert übergeben, der nicht "valide" ist. Wird etwas OT, aber ich poste es als Antwort, damit der Code lesbar ist.
Xantiva 21.03.2014

Stelle deine .net-Frage jetzt!