2010-01-24 399 views
7

我有这样的抽象类;获取静态泛型方法中的当前类型?

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

我想继承它,当我调用静态GetMyType()时,我想返回子类的类型。所以如果我声明一个子类型;

public class ConcreteProperty: PropertyBase {} 

然后当我打电话

var typeName = ConcreteProperty.GetMyType().Name; 

我希望 '的typeName' 设置为 “ConcreteProperty。”我怀疑有没有办法做到这一点,但如果有人知道如何获得这些信息,我很感兴趣。

(我试图解决的具体问题是在WPF依赖属性的详细程度,我很想能够做这样的事;

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

几乎有实现,但我不能完全得到我需要我的NameProperty类的信息)

+0

它是静态的原因是什么?声明为虚拟或抽象,您将遇到问题 – 2010-01-24 08:03:07

+0

为什么静态:这是一个奇怪的角度,而一个C#并非真正为此设计的。有时你的类型只能有一个值。所以'class Steve:Person {}'声明了一个类型,但由于只有一个可能的值,所以'Steve'类也标识了一个实例。宣布类型'史蒂夫'宣布单身'史蒂夫'。 WPF DP's就是这样;他们无法确定它们是实例数据,元数据还是类型。我试图将它们全部折叠成一个代码构造。这是所有投机ATM,但我有兴趣追求它自己。 – 2010-01-24 12:23:09

+0

这就是为什么我需要这个:为样板类型描述符代码生成部分类。动态创建的属性名称不能与该类型上定义的属性冲突,所以我需要类型内的属性名称列表进行检查。这是更多的样板代码,因此进入codegen。它也是静态的完美选择,因为它不会改变。所以我需要在静态构造函数中生成一个包含当前类型属性的列表。那么,地狱,现在我需要在T4模板中使用魔术字符串。 – Will 2010-05-21 14:32:19

回答

6

可以部分实现(通过继承深)仿制药的1级:

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

请注意,这仅适用于一个级别,如果您从ConcreteProperty下降,它仍然会从GetMyType返回ConcreteProperty。 – 2010-01-24 01:26:00

+0

的确如此。而这种方法的局限性之一。但它可能仍然有助于OP的依赖属性示例。 – LBushkin 2010-01-24 01:27:27

+0

这当然是迄今为止我见过的最好的方法;你可以在类型参数中创建对类型的引用来重新引用它。对我的例子来说,这很好地工作,虽然它给开发人员打了更多的打字。无论如何,这是最好的,并且非常有帮助。谢谢。 – 2010-01-24 12:25:13

4

子类位不起作用,因为静态方法绑定到一个类型。它是类型的方法,而不是实例的方法。子类型不包含基类型的静态方法,因为它们是不同的类型,并且静态方法绑定到基类型。尽管编译器可能允许您像通过派生类一样调用基类的静态方法,但实际上它将调用基类中的方法。这只是语法糖。出于同样的原因,你不能在子类中“重写”静态方法,因为它没有什么意义。

0

只是想知道为什么需要做这样的事情?

var typeName = ConcreteProperty.GetMyType().Name; 

反正你知道的类型,而调用该方法,你可以简单地做到这一点以及..

var typeName = typeof(ConcreteProperty).Name; 

万一你需要做到这一点,你可以用“阴影”覆盖子类中的基类的实现。

public class ConcreteProperty : PropertyBase { 

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

不幸的是,在我的示例代码中,我简化了它以将其减少到基本问题,并且这可以按照您所描述的方式解决。然而,我的解决方案需要的是能够为PropertyBase的任何子类询问“您的实际类型是什么”。例如,调用'this.GetType()'的方式总是获取实际类型而不是基本类型。 – 2010-01-24 12:28:29