Mit Case / Switch und GetType das Objekt bestimmen [Duplikat]
-
22-08-2019 - |
Frage
Mögliche Duplizieren:
C # - Gibt es eine bessere Alternative als diese 'Schalter auf Typ'?
Wenn Sie auf einem Objekttyp switch
wollen, was ist der beste Weg, dies zu tun?
Code-Snippet
private int GetNodeType(NodeDTO node)
{
switch (node.GetType())
{
case typeof(CasusNodeDTO):
return 1;
case typeof(BucketNodeDTO):
return 3;
case typeof(BranchNodeDTO):
return 0;
case typeof(LeafNodeDTO):
return 2;
default:
return -1;
}
}
Ich weiß, das nicht so funktioniert, aber ich frage mich, wie Sie dieses Problem lösen könnten.
Ist eine if/else
Aussage angemessen in diesem Fall?
oder verwenden Sie den Schalter und fügen .ToString()
den Typen?
Lösung
Wenn I wirklich hatte auf Objekttyp switch
, ich .ToString()
verwenden würde. Allerdings würde ich es auf jeden Fall vermeiden: IDictionary<Type, int>
wird viel besser, Besucher könnte ein viel des Guten aber ansonsten ist es immer noch eine ganz feine Lösung.
Andere Tipps
Dies wird nicht direkt lösen Ihr Problem, wie Sie auf Ihrem eigenen benutzerdefinierten Typen wechseln wollen, aber zum Wohle der anderen, die nur eingebauten Typen einschalten wollen, können Sie die Typecode Aufzählung:
switch (Type.GetTypeCode(node.GetType()))
{
case TypeCode.Decimal:
// Handle Decimal
break;
case TypeCode.Int32:
// Handle Int32
break;
...
}
In der MSDN-Blog-Post Viele Fragen: Schalter auf Art sind einige Informationen darüber, warum .NET bietet keine Einschalten Typen.
Wie üblich -. Abhilfen existieren immer
Dies ist nicht von mir, aber leider habe ich die Quelle verloren. Es macht auf Arten möglich Schalt, aber ich persönlich denke, es ist ziemlich umständlich (Wörterbuch Idee ist besser):
public class Switch
{
public Switch(Object o)
{
Object = o;
}
public Object Object { get; private set; }
}
/// <summary>
/// Extensions, because otherwise casing fails on Switch==null
/// </summary>
public static class SwitchExtensions
{
public static Switch Case<T>(this Switch s, Action<T> a)
where T : class
{
return Case(s, o => true, a, false);
}
public static Switch Case<T>(this Switch s, Action<T> a,
bool fallThrough) where T : class
{
return Case(s, o => true, a, fallThrough);
}
public static Switch Case<T>(this Switch s,
Func<T, bool> c, Action<T> a) where T : class
{
return Case(s, c, a, false);
}
public static Switch Case<T>(this Switch s,
Func<T, bool> c, Action<T> a, bool fallThrough) where T : class
{
if (s == null)
{
return null;
}
T t = s.Object as T;
if (t != null)
{
if (c(t))
{
a(t);
return fallThrough ? s : null;
}
}
return s;
}
}
Verbrauch:
new Switch(foo)
.Case<Fizz>
(action => { doingSomething = FirstMethodCall(); })
.Case<Buzz>
(action => { return false; })
Ich würde nur eine if-Anweisung verwenden. In diesem Fall:
Type nodeType = node.GetType();
if (nodeType == typeof(CasusNodeDTO))
{
}
else ...
Der andere Weg, dies zu tun ist:
if (node is CasusNodeDTO)
{
}
else ...
Das erste Beispiel gilt für genaue Typen nur, wo die letzteren Kontrollen für die Vererbung zu.
Ich bin mit dem gleichen Problem konfrontiert und über dieses Thema kam. Ist das, was durch den IDictionary Ansatz gemeint:
Dictionary<Type, int> typeDict = new Dictionary<Type, int>
{
{typeof(int),0},
{typeof(string),1},
{typeof(MyClass),2}
};
void Foo(object o)
{
switch (typeDict[o.GetType()])
{
case 0:
Print("I'm a number.");
break;
case 1:
Print("I'm a text.");
break;
case 2:
Print("I'm classy.");
break;
default:
break;
}
}
Wenn ja, kann ich nicht sagen, ich bin ein Fan von den Zahlen im Wörterbuch in Einklang zu bringen mit den Case-Anweisungen.
Das wäre ideal, aber die Wörterbuch Referenz tötet es:
void FantasyFoo(object o)
{
switch (typeDict[o.GetType()])
{
case typeDict[typeof(int)]:
Print("I'm a number.");
break;
case typeDict[typeof(string)]:
Print("I'm a text.");
break;
case typeDict[typeof(MyClass)]:
Print("I'm classy.");
break;
default:
break;
}
}
Gibt es eine andere Implementierung ich übersehen habe?
Sie können dies tun:
if (node is CasusNodeDTO)
{
...
}
else if (node is BucketNodeDTO)
{
...
}
...
Während das elegantere wäre, ist es möglicherweise nicht so effizient wie einige der anderen Antworten hier.
Sie können dies tun:
function void PrintType(Type t) {
var t = true;
new Dictionary<Type, Action>{
{typeof(bool), () => Console.WriteLine("bool")},
{typeof(int), () => Console.WriteLine("int")}
}[t.GetType()]();
}
Es ist klar, und seine leicht. Es ist ein wenig langsamer als das Wörterbuch irgendwo Cachen .. aber für viele Code wird dies ohnehin keine Rolle ..
Ein Ansatz ist es, einen rein virtuelles GetNodeType () -Methode NodeDTO hinzuzufügen und es in den Nachkommen überschreiben, so dass jeder Nachkomme tatsächlichen Typen zurückzugibt.
Je nachdem, was Sie in der Switch-Anweisung tun, ist die richtige Antwort Polymorphismus. Legen Sie einfach eine virtuelle Funktion in der Schnittstelle / Basisklasse und überschreibt für jeden Knotentyp.
ich eigentlich lieber den Ansatz als die Antwort, die hier gegeben: Gibt es eine bessere Alternative als dies zu 'Schalter auf Typ'?
Es gibt aber ein gutes Argument über keine Art Vergleich methids in einer objektorientierten Sprache wie C # implementieren. Sie könnten als Alternative erweitern und fügen Sie zusätzliche erforderliche Funktionalität Vererbung.
Dieser Punkt wurde in den Kommentaren der Autoren Blog hier diskutiert: http: // blogs. msdn.com/b/jaredpar/archive/2008/05/16/switching-on-types.aspx#8553535
Ich fand das einen äußerst interessanten Punkt, der meinen Ansatz in einer ähnlichen Situation geändert und nur hoffen, dass dies hilft andere.
Mit freundlichen Grüßen, Wayne