Подтвердить что ты не робот

Кастинг родового типа "как T", в то время как принудительный тип T

Мне не хватает трюка здесь, я думаю, и не могу поверить, что я никогда не делал этого раньше. Однако, как я могу использовать общий тип, используя ключевое слово as?

[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; вызывает следующую ошибку:

Невозможно использовать параметр типа T с оператором 'as', потому что он не имеют ограничения типа класса или Ограничение класса

Теперь, я думаю, понимаю причину этого; Я физически не сказал компилятору, что T - класс. Если я заменю:

public abstract class SessionManager<T> where T : ISessionManager

с

public abstract class SessionManager<T> where T : class

... тогда код успешно завершится.

Но мой вопрос таков; как я могу использовать как класс, так и ISessionManager для общего типа? Я надеюсь, что для этого будет очень простой ответ.

EDIT: Просто добавлю, что я попытался: where T : ISessionManager, class, оказалось, что я неправильно прочитал мою ошибку компилятора. Достаточно просто положить класс до ISessionManager. Ошибка, которую я не читал:

"Ограничение 'class' или 'struct' должен прийти перед любым другим ограничений".

Глубинный момент.

4b9b3361

Ответ 1

... where T : class, ISessionManager

Если вы хотите использовать методы keyword on здесь, это пример, который также использует 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 ;
    }

Ответ 2

where T : class, ISessionManager

вы можете пойти еще дальше

where T : class, ISessionManager, new()

это приведет к тому, что не абстрактный класс с параметрическим ctor будет передан как T