Кастинг родового типа "как 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' должен прийти перед любым другим ограничений".
Глубинный момент.
Ответы
Ответ 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
Ответ 3
Прочитайте Ограничения на параметрах типа в С#.
В этом конкретном случае вы должны убедиться, что T является классом:
public abstract class SessionManager<T>
where T : class, ISessionManager