2009-11-12 11 views
20

Me falta un truco aquí, creo y no puedo creer que nunca he hecho esto antes. Sin embargo, ¿cómo puedo lanzar un tipo genérico usando la palabra clave as?Casting genérico tipo "como T" mientras se aplica el tipo de 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; 

} 

La línea de tiros T manager = session[UniqueId] as T; el siguiente error:

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

Ahora, creo comprender la razón de esto; No le he dicho físicamente al compilador que T es una clase. Si sustituyo:

public abstract class SessionManager<T> where T : ISessionManager 

con

public abstract class SessionManager<T> where T : class 

... entonces el código se genera correctamente.

Pero mi pregunta es así; ¿Cómo puedo tener las ejecuciones de clase e ISessionManager en el tipo genérico? Espero que haya una respuesta muy simple para esto.

EDIT: sólo para añadir que había intentado: where T : ISessionManager, class, resulta que no había leído mi error del compilador correctamente. Simplemente, poner la clase antes de ISessionManager soluciona el problema. El error que no había leído era:

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

Dumb moment over.

+2

Por cierto, no se debe usar '' CreateInstance aquí. Debería agregar una restricción 'new()' y simplemente usar 'new T()' en el código. –

+0

¡Nunca lo sabía! Gracias. – GenericTypeTea

Respuesta

37
... where T : class, ISessionManager 

En caso de que quiera utilizar el dónde keyword en los métodos aquí es un ejemplo que también utiliza los genéricos

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 **. Estuve escribiendo donde T: ¡ISessionManager, clase! – GenericTypeTea

+7

Eso me enseñará a leer los errores del compilador correctamente. – GenericTypeTea

15
where T : class, ISessionManager 

puede ir aún más lejos

where T : class, ISessionManager, new() 

esta voluntad fuerza la clase no abstracta con ctor sin parámetros para ser entregada como T

4

Lea en Constraints on Type Parameters in C#.

En este caso particular, debe asegurarse de que T es una clase:

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

Eso no se compilará. ;) la clase tiene que ser lo primero. Además, todas las restricciones para un tipo particular se deben especificar en una sola cláusula where ... – GenericTypeTea

+0

Tienes razón, olvidé la sintaxis, corregida. –

+0

+1 para actualizar. – GenericTypeTea

Cuestiones relacionadas