C#通用奇怪

时间:2013-12-10 03:16:30

标签: c#

考虑以下

public class MyBuilder {}

public interface IBuilder
{
    MyBuilder Builder { get; }
}

public class TestGeneric<B, S> where B : IBuilder, new()where S : MyBuilder
{
    public TestGeneric()
    {
        B b = new B();
        S s = b.Builder ;// as S;
    }
}

编译器抱怨:

  

无法将“MyBuilder”类型隐式转换为“S”。一个明确的   转换存在......

为什么不呢? 毕竟我明确地说明了 S:MyBuilder ,这是一个base类。

此外,我认为Parameter Invariance不适用于此。 this SO问题类似,但我没有看到答案。 我正在使用VS 2013和.Net 4.5。当然还有演员。

编辑:我之前有一个密封的课程。

3 个答案:

答案 0 :(得分:2)

您应该收到以下错误

  

CS0701:'System.Text.StringBuilder'不是有效约束。用作约束的类型必须是接口,非密封类或类型参数。

答案 1 :(得分:2)

  

毕竟我明确地说明了S : MyBuilder,它是一个基类。

是的,但您正试图向上转播 MyBuilderS,除非S {{ 1}}:

MyBuilder

会尝试将TestGeneric<IBuilderImpl,MyNewBuilder> g; 转换为MyBuilder,这会在运行时失败。

答案 2 :(得分:0)

我并不完全相信所以我继续挖掘和骚扰同事! 这是答案from MSFT

For reference types, an explicit cast is required if you need to convert from a base type to a derived type

这正是这里的情况,正如我的同事亚历克斯指出的那样:

S inherits from MyBuilder, is not the same as "S.GetType() == typeof(MyBuilder)"

SO question也验证我的断言