Brakuje mi tutaj pewnej sztuczki i nie mogę uwierzyć, że nigdy tego nie robiłem. Jednak w jaki sposób mogę rzucić typ ogólny za pomocą słowa kluczowego as?Rzut typem ogólnym "jako T" podczas wymuszania typu 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;
}
Linia T manager = session[UniqueId] as T;
wyrzuca następujący błąd:
The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint
Teraz myślę zrozumieć przyczynę tego; Nie powiedziałem fizycznie kompilatorowi, że T jest klasą. Jeśli mogę wymienić:
public abstract class SessionManager<T> where T : ISessionManager
z
public abstract class SessionManager<T> where T : class
... wtedy kod buduje pomyślnie.
Ale moje pytanie jest w ten sposób; jak mogę mieć egzekwowanie zarówno klasy, jak i menedżera ISessionManager w typie ogólnym? Mam nadzieję, że jest na to bardzo prosta odpowiedź.
EDIT: Wystarczy dodać próbowałem: where T : ISessionManager, class
, okazuje się, że nie czytał mój błąd kompilatora prawidłowo. Wystarczy, że samo ustawienie klasy przed ISessionManager
rozwiązuje problem. Błąd, którego nie przeczytałem:
"The 'class' or 'struct' constraint must come before any other constraints".
Głupi moment.
BTW, nie należy używać '' CreateInstance tutaj. Powinieneś dodać ograniczenie 'new()' i po prostu użyć 'new T()' w kodzie. –
Nigdy tego nie wiedziałem! Dzięki. – GenericTypeTea