2010-01-15 13 views
5

Esto puede parecer una especie de "tarea para el hogar" y/o trivial, pero tiene un propósito comercial real; es la manera más fácil que se me ocurre para explicar lo que intento conceptualmente hacer.Identificación de tipos derivados de una lista de objetos de la clase base

Supongamos que tengo una clase de Animal y algunas otras clases (Pájaro, Gato, Canguro). Cada uno de estos hereda de Animal.

animal podría tener este aspecto:

public class Animal 
{ 
    public Animal() 
    { 

    } 

    public string Name { get; set; } 
    public string AnimalType { get; set; } 
    public List<Animal> Friends { get; set; } 
} 

canguro podría tener este aspecto:

public class Kangaroo : Animal 
{ 
    public Kangaroo() 
    { 

    } 

    public int TailLengthInches { get; set; } 
} 

Supongamos que el canguro tiene dos amigos, un pájaro y un gato. ¿Cómo podría agregarlos a la lista de amigos "Animales" (como tipo Animal), pero conservar la capacidad de acceder a las propiedades de las clases derivadas? (como en, todavía tengo que poder trabajar con propiedades que sean específicas para el tipo de animal, como FeatherColor para el ave, por ejemplo, aunque se consideren simplemente "animales".

La razón por la que Lo que trato de hacer es que cuando obtenga la lista de los "amigos" del animal, es vital que sepa qué tipo de animal es el amigo. Dependiendo del tipo de animal (ya sea un pájaro, un gato, etc.) Quiero hacer algo diferente (mostrar una plantilla diferente en una página ASP.NET, en realidad, pero no necesito ayuda con eso específicamente).

Supongo que se reduce a esto ... si tengo una lista de Animal, ¿cómo sé cuál fue el tipo derivado para cada uno de los objetos en la lista, por lo que puedo devolverlos a su tipo derivado o hacer algo más? at me permite llegar a las diferentes propiedades específicas que hay en cada tipo derivado?

Gracias!

+1

Consejo: para obtener el código para mostrar correctamente, utilice el botón de 101.010 en el editor (o guión por cuatro espacios) . – itowlson

Respuesta

7

Puede utilizar LINQ para filtrar el tipo que busca

animals.Friends = new List<Animal> { new Kangaroo(), new Bird() }; 
foreach (var kangaroo in animals.Friends.OfType<Kangaroo>()) { 
    kangaroo.Hop(); 
} 
+0

Esta es una manera realmente elegante de manejarlo. ¡Gracias! –

1

Prueba a transmitir es:

var friendBird = friend as Bird; 
if (friendBird != null) 
{ 
    // It's a bird, so do something with it 
) 
+0

+1 para usar la palabra clave 'as' para evitar el doble casting involucrado con la palabra clave' is' y luego lanzar el objeto. –

1

Puede utilizar typeof para obtener el tipo real, o utilizar los is o as operadores para probar y opcionalmente fundido:

foreach (Animal a in Friends) 
{ 
    Kangaroo k = a as Kangaroo; 
    if (a != null) 
    { 
    // it's a kangaroo 
    k.JumpAround(); 
    } 
    Ostrich o = a as Ostrich; 
    if (o != null) 
    { 
    o.StickHeadInSand(); 
    } 
} 

(yo no tengo usó las cláusulas else aquí, que podrían causar errores si está probando contra tipos que podrían estar en una jerarquía; por ejemplo, si tuviera ambas cláusulas, Kangaroo y Marsupial, ¡probablemente NO quisiera que se ejecutaran ambas!)

También puede hacer esto con el operador is, que se ve mejor, pero hará que FxCop grito:

foreach (Animal a in Friends) 
{ 
    if (a is Kangaroo) 
    { 
    ((Kangaroo)a).JumpAround(); 
    } 
} 

En general, dicho sea de paso, es probable que desee buscar una oportunidad de poner un método virtual en Animal e implementar ese método de forma polimórfica, en lugar de tener declaraciones monstruosas if que dan como resultado un acoplamiento frágil a un conjunto específico de clases derivadas.

0

Utilice la palabra clave 'es'.

if (animal es pájaro) ...

0
animals.Friends = new List<Animal> { new Kangaroo(), new Bird() }; 
foreach (Animal animal in animals.Friends) 
{ 
if (animal is Kangaroo) 
Console.WriteLine("Kangaroo"); 
else if (animal is Bird) 
Console.WriteLine("Bird"); 
} 
Cuestiones relacionadas