2011-10-17 115 views
1

說我有下面的類:檢查泛型參數在編譯時

public class MyClass<T> 
{ 
    public MyClass() { 
     //construct logic 
    } 

    public IProperty<T> MyProperty { get; set; } 
} 

public interface IProperty<T> { } 

public DateTimeProperty : IProperty<DateTime> 
{ 

} 

如果我嘗試把這個代碼進入MyClass構造:

if (typeof(T) == typeof(DateTime)) 
    MyProperty = new DateTimeProperty(); 

我得到以下編譯錯誤:如何在MyClass的構造函數中設置值MyProperty必須是new DateTimeProperty,只有T類型爲DateTime

+0

您是否嘗試過明確的轉換呢? – ordag

+0

使用該構造並不是真正意義上的泛型應用。 –

回答

3

請注意,泛型應該確實如此; generic;你在做什麼是專門(對於一些T),這是不是重點。但是,對於如何 - 投:

MyProperty = (IProperty<T>)(object)new DateTimeProperty(); 

通過強制轉換爲object,然後備份到(IProperty<T>)刪除編譯器的應用靜態類型檢查規則的能力。缺點是:你刪除了編譯器應用靜態類型檢查規則的能力。

+0

感謝您的回答Marc。我真的在整個這個類中使用泛型參數。更接近事實的是,我有一個'IProperty'集合,其中大多數是通用的,但其中一些是類型特定的。有沒有可以推薦的設計模式,這是實現這一目標的更好方法?也許每種類型的工廠類? – Connell

+0

@ConnellWatkins嗯...工廠聽起來像過度複雜它;儘量保持簡單直到你*需要複雜性。無論什麼作品... –

+0

是的,我考慮過工廠,但是正是這麼想的。有時你只需要知道什麼時候放入一些不那麼推薦的代碼就會更有效率。我可以創建一個靜態方法來接受'MyClass '對象並將'MyProperty'設置爲'new DateTimeProperty()'?靜態類型檢查規則在這裏仍然適用,不是嗎? – Connell

0

我認爲你不應該這樣做,因爲那時泛型不是泛型的,正如Marc所說的,如果你有一個基類實現你所需要的,並且你想限制MyClass只被創建爲源自你的類型基類可以使用where (generic type constraint) (C# Reference)

public class MyClass<T> where T : YourBaseClass 
+1

我的解釋是,他不是什麼*所有* T'被限制爲'DateTime',而是:當'T' ***是***'DateTime'時,應用一些專業化。 –

1

雖然這只是一個風格不同,我喜歡馬克的建議下過:

((MyClass<DateTime>)this).MyProperty = new DateTimeProperty(); 
+0

這很整潔,我喜歡這個。我甚至可以使用'as'關鍵字來避免類型檢查,然後轉換:'MyClass dt = this as MyClass ; if(dt!= null){dt.MyProperty = new DateTimeProperty(); }' – Connell