2010-01-24 93 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