2009-08-02 19 views
11

Voy a empezar por explicar mi escenario en el código:C# .NET - ¿Cómo puedo obtener typeof() para trabajar con la herencia?

public class A { } 

public class B : A { } 

public class C : B { } 

public class D { } 

public class Test 
{ 
    private A a = new A () ; 
    private B b = new B () ; 
    private C c = new C () ; 
    private D d = new D () ; 

    public Test () 
    { 
     // Evaluates to "false" 
     if (a.GetType == typeof(B)) { } //TODO: Add Logic 

     // Evaluates to "true" 
     if (b.GetType == typeof(B)) { } //TODO: Add Logic 

     // I WANT this to evaluate to "true" 
     if (c.GetType == typeof(B)) { } //TODO: Add Logic 

     // Evaluates to "false" 
     if (d.GetType == typeof(B)) { } //TODO: Add Logic 
    } 
} 

La línea importante tomar nota de que aquí es:

if (c.GetType == typeof(B)) { } 

que creen que esto, de hecho, se evalúa como " falso ", ya que typeof (B) y typeof (C) no son iguales entre sí en ambas direcciones. (C es una B, pero B no es necesariamente una C.)

Pero lo que necesito es algún tipo de condición que tenga esto en cuenta. ¿Cómo puedo saber si un objeto es un B o algo derivado de él?

No me importa si se trata de un objeto DERIVADO de B, siempre que la clase B base esté allí. Y no puedo anticipar qué clase derivada podría aparecer en mi aplicación. Solo tengo que suponer que las clases derivadas desconocidas pueden existir en el futuro y, por lo tanto, solo puedo enfocarme en asegurarme de que la clase base es lo que estoy esperando.

Necesito una condición que realice esta comprobación por mí. ¿Cómo se puede lograr esto?

+0

Debe evitar este tipo de lógica cuando sea posible. Cuando tiene que determinar cuál es el tipo derivado de un objeto, no está haciendo un buen uso del polimorfismo. –

+0

Ver mi comentario sobre la respuesta de Steven Sudit. – Giffyguy

Respuesta

36

sólo puede utilizar is:

if (c is B) // Will be true 

if (d is B) // Will be false 
+0

Como respuesta a la única pregunta real en el PO: "¿Cómo puedo saber si un objeto es un B o algo derivado de él?" Esta es la respuesta correcta. La mía es la respuesta al título de la secuencia, pero menos apropiada para el problema descrito. –

+0

Ah, es verdad. Estás en lo correcto, mi pregunta es un poco confusa. Mi error. – Giffyguy

+0

+1 Esta es la solución correcta para este problema. –

19

Editar: esto responde la pregunta en el título de la secuencia. cdm9002 tiene la mejor respuesta al problema como se describe en la publicación completa.

typeof(B).IsAssignableFrom(c.GetType()) 
+2

La respuesta de cdm9002 es mejor, ya que no utiliza la reflexión. –

+0

@pb: si desea obtener información técnica, la otra respuesta no utiliza 'typeof' con la herencia. Como puede ver en mi edición, no soy de los que afirman que la primera respuesta que pensé es la más adecuada.:) –

+2

Esta no solo es la respuesta correcta, sino que además cubre el caso cuando no tiene instancias de ninguna de las clases disponibles, pero aún desea determinar si existe una relación de herencia entre dos tipos. –

4

Esto parece un trabajo para el polimorfismo, en oposición a una sentencia switch grande con pruebas para clases específicas.

+0

De hecho. Ponga un método virtual en la clase A, anule según corresponda en subclases, luego llame a este método virtual. –

+1

¡Qué grosero! Jaja. Mi lógica de clase en realidad no se ve así. Solo necesitaba descubrir cómo realizar esta condición. Estoy escribiendo un método PropertyChangedCallback IN en la clase base abstracta, y necesito una condición de seguridad que garantice que el parámetro DependencyObject sea un objeto derivado de mi clase base. Si no, arrojo un error o cancelo mi lógica. El polimorfismo no es útil en este caso. – Giffyguy

+1

Ok, entonces usar "es" debería ser suficiente. –

0

para VB.NET con Visual Studio     2008, se puede comprobar como:

'MyTextBox control is inherited by Textbox 
If Ctl.GetType.Name = "MyTextBox" then  

End If 
1

Como alternativa a la comprobación (c is B), también puede hacer lo siguiente:

var maybeB = c as B; 
if (maybeB != null) { 
    // make use of maybeB 
} 

Esto es preferible en algunos casos ya que para usar c como B al usar is, debería emitir de todos modos.

0
typeof(B).IsInstanceOfType(c) 

Similar a la respuesta anterior de Sam-Harwell, a veces puede tener el tipo "B" en una variable, por lo que necesita para utilizar la reflexión más que el "es" operador.

Utilicé la solución de Sam, y me sorprendió gratamente cuando Resharper hizo esta sugerencia.

Cuestiones relacionadas