通用约束和接口实现/继承

时间:2009-01-07 00:33:41

标签: c# generics

不完全确定如何说出问题,因为这是“为什么这不起作用?”查询类型。

我已将我的特定问题缩减到此代码:

public interface IFoo
{
}

public class Foo : IFoo
{
}

public class Bar<T> where T : IFoo
{
    public Bar(T t)
    {
    }

    public Bar()
        : this(new Foo()) // cannot convert from 'Foo' to 'T'
    {
    }
}

现在,T中的泛型类型Bar<T>必须实现IFoo。那么为什么编译器会在评论中给出错误?当然,Foo的一个实例是一个IFoo,因此可以作为泛型T的代表传递?

这是编译器限制还是我遗漏了什么?

3 个答案:

答案 0 :(得分:13)

您还可以使用Fiz以任何其他方式实现与Foo无关的IFoo:

public interface IFoo
{
}

public class Foo : IFoo
{
}

public class Fiz : IFoo
{
}

Foo foo = new Foo();
Fiz fiz = foo; // Not gonna compile.

你想要的更像是:

public class Bar<T> where T : IFoo, new()
{
    public Bar(T t)
    {
    }

    public Bar()
        : this(new T()) 
    {
    }
}

所以你可以拥有

Bar<Foo> barFoo = new Bar<Foo>();
Bar<Fiz> barFiz = new Bar<Fiz>();

答案 1 :(得分:2)

如果你创建一个Baz类,然后是泛型类型Bar baz = new Bar(),你的构造函数重载定义的新Foo()将不是T类型,在本例中是Baz。

答案 2 :(得分:0)

这是因为如果你创建一个类:

public class Fred : IFoo
{
}

然后像这样实例化Bar<T>

var bar = new Bar<Fred>();

然后它违反了类的约束,因为Foo不是Fred,它是当前的T

您可以通过在构造函数中放置强制转换序列(T)(IFoo)new Foo()来强制进行编译,但如果InvalidCastException的实际类型不能从T分配,那么您将在运行时获得Foo {{1}}。