Pregunta

  

Duplicar posible:
   C # - ¿Hay una mejor alternativa que esto para 'encender tipo'?

Si desea switch en un tipo de objeto, lo que es la mejor manera de hacer esto?

Fragmento de código

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;
    }
}

Sé que esto no funciona de esa manera, pero me preguntaba cómo se podría solucionar esto. Es una declaración if/else apropiado en este caso?

O Cómo se utiliza el interruptor y agrega .ToString() al tipo?

¿Fue útil?

Solución

Si I realmente tuvieron que switch el tipo de objeto, que haría uso de .ToString(). Sin embargo, me volvería a evitar a toda costa: IDictionary<Type, int> va a hacer mucho mejor, visitante podría ser una exageración pero por lo demás es todavía una solución perfectamente bien.

Otros consejos

Esto no va a resolver directamente el problema, ya que quiere encender sus propios tipos definidos por el usuario, sino para el beneficio de otros que sólo se desea encender tipos incorporados, se puede utilizar el TypeCode enumeración:

switch (Type.GetTypeCode(node.GetType()))
{
    case TypeCode.Decimal:
        // Handle Decimal
        break;

    case TypeCode.Int32:
        // Handle Int32
        break;
     ...
}

En la entrada del blog de MSDN Muchas preguntas: Interruptor del tipo de es un poco de información sobre por qué .NET no proporciona encender tipos.

Como de costumbre -. Siempre existe soluciones

Éste no es el mío, pero por desgracia he perdido la fuente. Se hace que el cambio en los tipos posibles, pero yo personalmente creo que es bastante incómodo (la idea diccionario es mejor):

  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;
      }
  }

Uso:

 new Switch(foo)
     .Case<Fizz>
         (action => { doingSomething = FirstMethodCall(); })
     .Case<Buzz>
         (action => { return false; })

Me acabo de utilizar una sentencia if. En este caso:

Type nodeType = node.GetType();
if (nodeType == typeof(CasusNodeDTO))
{
}
else ... 

La otra manera de hacer esto es:

if (node is CasusNodeDTO)
{
}
else ...

El primer ejemplo es cierto para tipos exactos solamente, cuando este último comprueba herencia también.

me encuentro ante el mismo problema y me encontré con este post. Es esto lo que se quiere decir con el enfoque IDictionary:

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;
    }
}

Si es así, no puedo decir que soy un fan de la conciliación de los números en el diccionario con las declaraciones de casos.

Esto sería lo ideal, pero la referencia de diccionario de la mata:

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;
    }
}

¿Hay alguna otra aplicación que he pasado por alto?

Usted puede hacer esto:

if (node is CasusNodeDTO)
{
    ...
}
else if (node is BucketNodeDTO)
{
    ...
}
...

Mientras que sería más elegante, es posiblemente no tan eficiente como algunas de las otras respuestas aquí.

Usted puede hacer esto:

function void PrintType(Type t) {
 var t = true;
 new Dictionary<Type, Action>{
   {typeof(bool), () => Console.WriteLine("bool")},
   {typeof(int),  () => Console.WriteLine("int")}
 }[t.GetType()]();
}

Está claro y es fácil. Es un poco más lento que el almacenamiento en caché el diccionario algún lugar .. pero para una gran cantidad de código que esto no importa de todos modos ..

Un enfoque consiste en añadir un método GetNodeType virtual pura () para NodeDTO y anular que en los descendientes de manera que cada descendiente devuelve tipo real.

En función de lo que está haciendo en la sentencia switch, la respuesta correcta es polimorfismo. Sólo hay que poner una función virtual en la clase de interfaz / base y anular para cada tipo de nodo.

En realidad, prefiero el enfoque dado como respuesta aquí: ¿Existe una alternativa mejor que esto a 'encender tipo'?

No obstante es un buen argumento sobre el que no efectúe ninguna methids de comparación de tipos en un lenguaje orientado a objetos como C #. Se podría como alternativa extender y añadir funcionalidad requerida capacidad utilizando herencia.

Este punto fue discutido en los comentarios del blog autores aquí: http: // blogs. msdn.com/b/jaredpar/archive/2008/05/16/switching-on-types.aspx#8553535

He encontrado este un punto extremadamente interesante, que cambió mi enfoque en una situación similar y sólo espero que esto ayude a otros.

Saludos cordiales, Wayne

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top