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

Viewed 17222

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.

3 Answers
Related