2010-01-24 22 views
7

Tengo una clase abstracta como esta;Obteniendo el tipo actual en un método genérico estático?

public abstract PropertyBase 
{ 
    public static System.Type GetMyType() 
    { 
     return !!!SOME MAGIC HERE!!! 
    } 
} 

me gustaría hacerla una subclase, y cuando llamo al GetMyType estática(), me gustaría volver tipo de la subclase. Entonces si declaro un subtipo;

public class ConcreteProperty: PropertyBase {} 

entonces cuando llamo

var typeName = ConcreteProperty.GetMyType().Name; 

espero 'typeName' a ponerse en "ConcreteProperty." Sospecho que no hay forma de hacerlo, pero estoy interesado si alguien conoce una manera de obtener esta información.

(El problema particular que estoy tratando de resolver es el nivel de detalle de las propiedades de dependencia en WPF, me encantaría ser capaz de hacer algo como esto;

class NamedObject : DependencyObject 
{ 
    // declare a name property as a type, not an instance. 
    private class NameProperty : PropertyBase<string, NamedObject> { } 

    // call static methods on the class to read the property 
    public string Name 
    { 
     get { return NameProperty.Get(this); } 
     set { NameProperty.Set(this, value); } 
    } 
} 

Y casi tener una aplicación, pero no puedo bastante obtener la información que necesito de mi clase NameProperty)

+0

¿Cuál es la razón por la cual es estático? Declarado como virtual o abstracto, tendrías el problema –

+0

POR QUÉ ESTÁTICO: Es un ángulo extraño, y un C# no está diseñado para. Algunas veces su tipo solo puede tener un valor. Entonces 'clase Steve: Persona {}' declara un tipo, pero como solo hay un valor posible, la clase 'Steve' también identifica una instancia. Declarar el tipo 'Steve' declara el singleton 'Steve'. WPF DP son así; no pueden decidir si son datos de instancia, metadatos o tipos. Estoy tratando de doblarlos a todos en una construcción de código. Todo es cajero automático especulativo, pero estoy interesado en seguirlo por su propio bien. –

+0

He aquí por qué necesito esto: generación de una clase parcial para el código descriptivo TypeDescriptor. Los nombres de propiedad creados dinámicamente no pueden entrar en conflicto con las propiedades definidas en el tipo, por lo que necesito una lista de los nombres de propiedad dentro del tipo para hacer una verificación. Este es un código más repetitivo y, por lo tanto, va en codegen. También es un candidato perfecto para estática, ya que no cambia.Entonces, necesito generar una lista que contenga propiedades del tipo actual dentro de un constructor estático. Bueno, demonios, ahora necesito usar cadenas mágicas en la plantilla T4. – Will

Respuesta

6

se puede lograr parcialmente (1-nivel de herencia de profundidad) usando genéricos:.

class PropertyBase<T> 
{ 
    public static Type GetMyType() { return typeof (T); } 
} 

// the base class is actually a generic specialized by the derived class type 
class ConcreteProperty : PropertyBase<ConcreteProperty> { /* more code here */ } 

// t == typeof(ConcreteProperty) 
var t = ConcreteProperty.GetMyType(); 
+0

Tenga en cuenta que esto solo funciona en un nivel, si desciende de ConcreteProperty, todavía devolverá ConcreteProperty de GetMyType. –

+0

Eso es verdad. Y una de las limitaciones de este enfoque. Pero aún puede ayudar con el ejemplo de propiedad de dependencia del OP. – LBushkin

+0

Este es ciertamente el mejor enfoque que he visto hasta ahora; usted crea la referencia al tipo, recíclela en los parámetros de tipo. Para mi ejemplo, esto funciona bien, aunque impone un poco más de tipeo en el desarrollador. De todos modos, este es el mejor hasta ahora, y muy útil. Gracias. –

4

El bit de subclases no funcionará, porque un método estático está vinculado a un tipo. Es un método de un tipo, no un método de una instancia. El subtipo no contiene los métodos estáticos de un tipo base, porque son tipos diferentes y el método estático está vinculado al tipo base. Aunque el compilador podría permitirle llamar a un método estático de una clase base como a través de una clase derivada, en realidad llamará al método desde la clase base. Es solo azúcar sintáctico. Por la misma razón, no puede "anular" los métodos estáticos en subclases porque tendría poco sentido.

0

Me pregunto por qué tendrían que hacer algo como esto?

var typeName = ConcreteProperty.GetMyType().Name; 

De todos modos se sabe el tipo al llamar al método, se puede simplemente hacer esto, así ..

var typeName = typeof(ConcreteProperty).Name; 

Sólo en caso de tener que hacer esto, puede utilizar "sombra" para anular la implementación de la clase base en la clase infantil.

public class ConcreteProperty : PropertyBase { 

     public new static Type GetMyType { 
      //provide a new implementation here 
     } 
    } 
+0

Desafortunadamente en mi código de ejemplo lo he simplificado para reducirlo al problema esencial, y esto podría resolverse de la manera que usted ha descrito. Lo que mi solución requiere, sin embargo, es la capacidad de preguntar, para cualquier subclase de PropertyBase, 'cuál es tu tipo real'. La forma en que, por ejemplo, llamar a 'this.GetType()' siempre obtiene el tipo real en lugar de un tipo base. –

Cuestiones relacionadas