2009-11-12 110 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