带约束的模板化成员变量,不能转换,为什么?

Templated member variable with constraints, cannot cast, why?

全部,

我有以下 class 定义:

public class SessionScope<TSession> : ISessionScope<TSession>
        where TSession : class, IStatefulSession
    {
        private TSession _session; // Constraint as IStatefulSession
    }

那为什么我不能做这个转换:

_session = HibernateContext.Current.AcquireNewSession(); // AcquireNewSession() returns IStatefulSession

这是编译器消息: 无法将类型 'xxx.Persistence.IStatefulSession' 隐式转换为 'TSession'。存在显式转换(是否缺少强制转换?)

但我可以做到:

_session = (TSession)HibernateContext.Current.AcquireNewSession();

有关详细信息,请查看 https://docs.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance

简短版本基本上是 AcquireNewSession returns 一个接口 IStatefulSession,比 TSession 更不具体,class 实现了该接口。

您必须明确地将不太具体的类型转换为更具体的类型,这是可能的,因为给定的约束。

然而,换一种方式总是好的,因为我们总是可以将更具体的类型分配给不太具体的类型。

这与您始终可以将 string 分配给 object 变量的原因基本相同,但是如果要将其分配给 object 则必须显式转换 object =13=]变量。