2009-11-12 113 views
20

我錯過了一個技巧,我認爲我不能相信我從來沒有這樣做過。但是,如何使用as關鍵字來施放泛型類型?鑄造泛型類型「爲T」,同時強制執行類型T

[Serializable] 
public abstract class SessionManager<T> where T : ISessionManager 
{ 

    protected SessionManager() { } 

    public static T GetInstance(HttpSessionState session) 
    { 

     // Ensure there is a session Id 
     if (UniqueId == null) 
     { 
      UniqueId = Guid.NewGuid().ToString(); 
     } 

     // Get the object from session 
     T manager = session[UniqueId] as T; 
     if (manager == null) 
     { 
      manager = Activator.CreateInstance<T>(); 
      session[UniqueId] = manager; 
     } 

     return manager; 

    } 

    protected static string UniqueId = null; 

} 

T manager = session[UniqueId] as T;引發以下錯誤:

The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint

現在,我想知道這樣做的原因;我沒有實際告訴編譯器T是一個類。如果我更換:

public abstract class SessionManager<T> where T : ISessionManager 

public abstract class SessionManager<T> where T : class 

...然後代碼成功生成。

但是我的問題是這樣的;我如何在泛型類型上同時實現類和ISessionManager強制?我希望有一個非常簡單的答案。

編輯: 我想補充我曾嘗試:where T : ISessionManager, class,原來我已經無法正確讀取我的編譯器錯誤。簡單地說,只需在ISessionManager之前安排課程即可解決問題。我沒有看到的錯誤是:

"The 'class' or 'struct' constraint must come before any other constraints".

沉默寡言的時刻結束。

+2

順便說一句,你不應該使用'的CreateInstance '這裏。你應該添加一個'new()'約束,並簡單地在代碼中使用'new T()'。 – 2009-11-12 12:24:09

+0

永遠不會知道!謝謝。 – GenericTypeTea 2009-11-12 12:34:19

回答

37
... where T : class, ISessionManager 

如果你想使用這裏keyword放在這裏的方法則是使用泛型

public void store<T>(T value, String key) 
    { 
     Session[key] = value; 
    } 

    public T retrieve<T>(String key) where T:class 
    { 
     return Session[key] as T ; 
    } 
+0

Ar **。我一直在寫T:ISessionManager,class! – GenericTypeTea 2009-11-12 12:08:38

+7

這會教會我正確地讀取編譯器錯誤。 – GenericTypeTea 2009-11-12 12:09:41

15
where T : class, ISessionManager 

你可以更進一步

where T : class, ISessionManager, new() 

這個意志爲轉移的例子用非參數化的非抽象類強制交出T

4

閱讀Constraints on Type Parameters in C#

在這種特殊情況下,你必須確保T是一個類:

public abstract class SessionManager<T> 
    where T : class, ISessionManager 
+3

這不會構建。 ;)班必須先到。另外,特定類型的所有約束必須在單個where子句中指定... – GenericTypeTea 2009-11-12 12:11:37

+0

你說得對,我忘記了語法,修正了。 – 2009-11-12 14:03:25

+0

+1更新。 – GenericTypeTea 2009-11-12 15:16:53