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?

War es hilfreich?

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top