c# 7.0: Anlage einschalten.Geben
Nicht vorhandene Frage hat eine Antwort auf diese Frage.
In c# 7, kann ich den Schalter direkt auf eine System.Type
?
Wenn ich versuche:
switch (Type)
{
case typeof(int):
break;
}
sagt es mir, dass typeof(int)
muss ein konstanter Ausdruck sein.
Gibt es einige syntatic Zucker, dass mir erlaubt, zu vermeiden case nameof(int):
und direkt vergleichen die Arten für die Gleichstellung? nameof(T)
in einer case-Anweisung ist nicht ganz gut, weil namespaces. So, obwohl der name Kollision ist wahrscheinlich nicht anwendbar für int
es gilt für andere Vergleiche.
In anderen Worten, ich versuche, mehr direkte als diese:
switch (Type.Name)
{
case nameof(Int32):
case nameof(Decimal):
this.value = Math.Max(Math.Min(0, Maximum), Minimum); //enforce minimum
break;
}
In c# 7, can I switch directly on a System.Type?
Wenn man bedenkt, dass haben Sie die Antwort auf diese Ihre Frage, warum noch Fragen? Sie kennen die Antwort.Nein, habe ich nicht. Mein Beispiel ist nicht die Antwort. Es ist das Gegenbeispiel.
Anstatt mit einem Schalter, können Sie bauen eine
Dictionary<Type, Action>
aufrufen der Funktion Sie möchten für einen bestimmten Typ? Würde der code sauberer sein, dass der Weg, denke ich.it tells me that typeof(int) needs to be a constant expression.
Das ist buchstäblich die Antwort auf Ihre Frage.Vielleicht sollten Sie erklären, warum Sie wechseln wollen, auf
System.Type
, wenn Sie können, wechseln Sie einfach auf den Wert? Ich denke, man müsste typeof(value)
vor.
InformationsquelleAutor toddmo | 2017-03-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den (bereits verlinkt) neue pattern-matching-Funktion ermöglicht dies.
Normalerweise würden Sie wechseln auf einen Wert:
Aber Sie können es verwenden, um umzuschalten auf eine Art, wenn alle Sie haben, ist ein Typ:
Beachten Sie, dass dies ist nicht das, was das feature ist dafür gedacht, es wird weniger lesbar als eine traditionelle
if
...else if
...else if
...else
Kette, und die traditionelle Kette ist, was es kompiliert trotzdem. Ich empfehle nicht, mithilfe von pattern matching wie diese.when
s? Stattcase Type t when (t == typeof(int) || t == typeof(decimal)) :
um Ihre bearbeiteten Kommentar) Mit
||
es ist nicht das, was die Verkettung wäre, aber keine Bedingung gültig ist, darunter eine aus mehreren Teilausdrücke kombiniert mit&&
,||
, und einem anderen Betreiber, die Sie mögen.Warum erklären Sie frische
Type
variable anstelle von verwerfen Muster:case var _ when type == typeof(int)
?Im Allgemeinen Fall: um zu verhindern, dass der switch-Wert ausgewertet wird, mehrere Male. In diesem Fall: ich weiß nicht, ob es besser wäre, aber es dürfte zumindest würde nicht schlimmer sein als das, was ich in meiner Antwort. Würde ich noch nicht verwenden, entweder wenn.
InformationsquelleAutor
Beginnend mit Paulustrious die Idee der Umschaltung auf eine Konstante, aber Streben für die Lesbarkeit:
Was lesbar ist, ist subjektiv. Ich habe etwas ähnliches in VB vor langer Zeit, so habe ich verwendet, um diese form (aber in VB die
bool _
war nicht nötig, so war es nicht gibt). Leider gibt es in c# diebool _
erforderlich. Ich bin mit c# 7.0 und ich denke, die Umschaltung auf eine Konstante kann nicht unterstützt werden, die in früheren Compiler, aber ich bin nicht sicher, so versuchen Sie Sie, wenn Sie möchten. Ich denke, es ist kindof amüsant, dass die S/A-code-Formatierer nicht kennenwhen
noch.Sie würde nicht wollen, dies zu tun, natürlich, wenn Sie Sie brauchen, die
case
variable, wie für die Unterklassen.Aber für beliebige Boolesche Ausdrücke, es ist mehr geeignet, zum Beispiel:
Einige werden argumentieren, das ist schlimmer als if..else. Das einzige was ich sagen kann ist
switch
Kräfte ein Pfad, und es ist unmöglich zu brechen, dieswitch
Anweisung selbst, aber es ist möglich, lassen Sie sich einelse
und brechen eine if..else in mehreren Aussagen unbeabsichtigt, möglicherweise Ausführung von zwei "Zweige" versehen.Einschalten
Type
ist wirklich nur eine willkürliche wechseln, denn was wir wirklich einschalten ist eine Eigenschaft der variable. Es sei denn, und bis wir tun könnencase typeof(int)
(case
auf etwas, dass nicht ein konstanter Ausdruck), wir stecken mit so etwas wie dieses, wenn wir nicht wollen, dass die Verwendung von string-Konstanten, die im Falle von Typ-Namen, die nicht in den Rahmen.else
. FYI. c# - V7 ist die erste version zu unterstützen, und die erste version, wo die Reihenfolge der case-Anweisungen einen Unterschied macht. Ich verstehe deine VB. Ich verwendet, Powerbuilder und hattechoose
Erklärung, die Gaben Sie ähnliche Fähigkeiten. Schließlich können mehrere 'ifs' in einer when-Klausel.InformationsquelleAutor toddmo
@toddmo vorgeschlagen, die folgenden:
...aber warum nicht noch weiter gehen in seinem Streben nach Einfachheit. Das folgende funktioniert genauso gut, ohne dass die
bool
Typ Qualifikation, noch die überflüssigen_
dummy-variable:InformationsquelleAutor Glenn Slayden
Die Frage, die hier von der OP ist, dass Sie nicht verwenden können, die neuen C# 7 Typ-basierte switch-Funktion, wenn Sie nicht über eine tatsächliche Instanz der switched-nach Typ zur Verfügung, und Sie stattdessen nur seine vermeintlichen
System.Type
. Die akzeptierte Antwort, wie folgt zusammengefasst, die gut funktioniert für genau diesen Typ passende (kleinere Verbesserungen, die hier gezeigt, aber siehe mein letztes Beispiel unten noch eine weitere Rationalisierung)......aber es ist wichtig zu beachten, dass für die abgeleitete Referenz-Typ-Hierarchien dieser wird nicht zeigen das gleiche Verhalten wie ein
if... else
Kette, die verwendet dieis
Schlüsselwort für das matching. Bedenken Sie:Seit
TDerived3
"ist-ein"TDerived2
beide Fälle behandelt werden, die von den früheren Zustand bei der Verwendung vonis
passenden. Dies unterstreicht die unterschiedliche Laufzeit-Semantik zwischen 'strict' oder 'genauen' Typ Gleichheit versus amore nuancierte Vorstellung von der Art Kompatibilität. Da die Typen in den OP ' s Frage warenValueType
primitive (die kann nicht abgeleitet werden-aus), der Unterschied konnte nicht egal. Aber wenn wir uns anpassen, die 'genauen Typ passenden" akzeptierte Antwort mit dem Beispiel-Klassen, die oben gezeigt, wir wird kommen zu einem anderen Ergebnis:In der Tat, C# 7 nicht selbst kompilieren ein
switch
- Anweisung entspricht derif /else
Sequenz, wie oben gezeigt. (n.b. Es scheint, wie sollte der compiler erkennt das als Warnung, sondern als ein Fehler, da das Harmlose Ergebnis ist nur ein Zweig der unzugänglichen code-eine Bedingung, die der compiler hält eine Warnung anderswo-und auch, wenn man bedenkt, dass der compiler nicht selbst erkennen, an alle, die scheinbar identische situation, in derif /else
version). Hier:In jedem Fall, das einer der alternativen Verhaltensweisen angemessen ist, oder ob es überhaupt ankommt, hängt von Ihrer Anwendung, also mein Punkt hier ist nur, um die Aufmerksamkeit auf die Unterscheidung. Wenn Sie feststellen, dass Sie brauchen, die mehr versierte Typ-Kompatibilität version der switch-Ansatz, ist hier, wie es zu tun:
Schließlich, wie ich bereits in einem anderen Antwort auf dieser Seite können Sie vereinfachen dadurch die Nutzung der
switch
Aussage sogar noch weiter. Da wir nur mit derwhen
Klausel Funktionalität, und da wir vermutlich noch die originalen gewechselt-auf-Instanz zur Verfügung, die in einer Variablen, gibt es keine Notwendigkeit zu erwähnen, dass die variable in derswitch
Anweisung, noch wiederholen Sie seinen Typ (Type
, in diesem Fall) in jedemcase
. Tun Sie einfach das folgende statt:Beachten Sie die
switch(true)
undcase(true)
. Ich empfehle diese einfachere Technik, wenn Sie sich nur auf diewhen
- Klausel (das heißt, mehr als nur die situation der Umstellung aufSystem.Type
wie hier beschrieben).InformationsquelleAutor Glenn Slayden
Fand ich eine einfache und effiziente Art und Weise. Es erfordert C# - V7 ausgeführt. Die
switch("")
bedeutet, dass alle Fälle zufrieden sein werden, bis zu derwhen
- Klausel. Es verwendet diewhen
Klausel zu betrachten, dietype
.Diese Blätter parmStrings mit...
System.Action 3.14159, 42, M-String theory, This is a stringBuilder, parameter[5] is null
Du hast Recht. Ich habe mir den code generiert und es ist einfach. Weit weniger teuer als einige der früheren solutiosn. Ich nicht der Meinung, dass die Variablen-Namen würde zu Verwirrung führen. Aber sobald Sie es gesehen haben und verstehen, es ist viel einfacher das nächste mal, wenn Sie über Sie kommen. Ich verwende die String-Variablen-Namen als Kommentare. Sagen, es gibt vier bool oder bool? Variablen. Ich nenne einmal den Fall, TTFN. (N=null). Die nächsten, sagen TxxT ist Bedingungen 1 & 4 echte und 2 & 3 irrelevant sind. Es macht es leicht zu finden und man muss natürlich den Standard zu fangen, diejenigen, die Sie vergessen haben.
Sie sollten den generierten code. Das wäre ziemlich interessant. Trotzdem, das wahre Problem liegt tiefer als verwirrend Wartungs-Entwickler, und ich bin nicht schlau genug ATM, um es zu erklären. Es hat damit zu tun, Dinge zu tun, die der compiler nicht durchsetzen. Ich denke, es wäre eher ein Problem, wenn die whenning variable war nicht
System.Type
, aber einige Basis-Typ mit vielen Unterklassen, wieSystem.Exception
zum Beispiel. Jedenfalls, die "Kommentar-Variablen" out-of-sync mit der whenning variable. Und wenn Sie denken, Sie würden niemals, Sie haven T traf mein co-Arbeitskräfte lolDer einzige Grund, warum ich verwendet, geben Sie in meinem whenning Wege ist, das ist, was der OP verlangt. In einer anderen Antwort, die ich greifen einige meiner echten code. Dies ist jedoch nicht die OP ' s Frage, so kann es entfernt werden..
Siehe meine Antwort, wo ich versuchte, Sie zu beseitigen den Nachteil der Unübersichtlichkeit der variable-Namen und verwirrende Schalter-Ausdruck.
InformationsquelleAutor Paulustrious
Hinzufügen, um die oben genannten Antworten, wenn Sie nicht brauchen, wird der Wert verwendet werden, innerhalb der case-Anweisung, , die Sie verwenden können _. Diese syntax kann verwendet werden, entfernen Sie eine unbenutzte variable Warnmeldung.
InformationsquelleAutor Karthikeyan VK
Hier ist eine alternative, die nicht kompilieren, da die Klassen fehlen:
InformationsquelleAutor Paulustrious