Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting generic type "as T" whilst enforcing the type of T

Tags:

I'm missing a trick here I think and can't believe I've never done this before. However, how can I cast a generic type using the as keyword?

[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;  } 

The line T manager = session[UniqueId] as T; throws the following 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

Now, I think understand the reason for this; I've not physically told the compiler that T is a class. If I replace:

public abstract class SessionManager<T> where T : ISessionManager 

with

public abstract class SessionManager<T> where T : class 

... then the code builds successfully.

But my question is thus; how can I have both the class and ISessionManager enforcements on the generic type? I'm hoping there's a very simple answer for this.

EDIT: Just to add I had tried: where T : ISessionManager, class, turns out I hadn't read my compiler error properly. Simply enough, just putting class before ISessionManager fixes the issue. The error I hadn't read was:

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

Dumb moment over.

like image 754
djdd87 Avatar asked Nov 12 '09 12:11

djdd87


People also ask

What is generic in TS?

Generics allow creating 'type variables' which can be used to create classes, functions & type aliases that don't need to explicitly define the types that they use. Generics makes it easier to write reusable code.

How do you pass a generic class as parameter in TypeScript?

Assigning Generic ParametersBy passing in the type with the <number> code, you are explicitly letting TypeScript know that you want the generic type parameter T of the identity function to be of type number . This will enforce the number type as the argument and the return value.

Does TypeScript have generics?

TypeScript supports generic classes. The generic type parameter is specified in angle brackets after the name of the class. A generic class can have generic fields (member variables) or methods.

How do generics work in TypeScript?

The TypeScript documentation explains Generics as “being able to create a component that can work over a variety of types rather than a single one.” Great! That gives us a basic idea. We are going to use Generics to create some kind of reusable component that can work for a variety of types.


1 Answers

... where T : class, ISessionManager 

In case you want to use the where keyword on methods here is an example that also uses generics

    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 ;     } 
like image 106
mmx Avatar answered Sep 25 '22 03:09

mmx