.NET 4 泛型问题

3
我有以下类结构:
public class A : AInterface { }
public interface AInterface { }

public class B<T> : BInterface<T> where T : AInterface 
{
    public T Element { get; set; }
}
public interface BInterface<T> where T : AInterface 
{
    T Element { get; set; }
}

public class Y : B<A> { }

public class Z<T> where T : BInterface<AInterface> {}

public class Test
{
    public Test()
    {
        Z<Y> z = new Z<Y>();
    }
}

在C# 4.0中,我遇到了以下编译错误:

类型'Test.Y'不能用作泛型类型或方法'Test.Z'中的类型参数'T'。从'Test.Y'到'Test.BInterface'没有隐式引用转换。

我认为泛型协变应该可以解决这个问题?感谢您的帮助。

2个回答

4

接口中的泛型参数默认是不变的,您需要明确指定是否希望特定的泛型参数是协变或逆变。基本上,在您的示例中,您需要向接口声明中添加“out”关键字:

public interface BInterface<out T> where T : AInterface { } 

您可以在MSDN上找到更多关于创建变体接口的信息:创建变体通用接口 (C# 和 Visual Basic)


感谢Alexandra。如果T是一个返回参数,这肯定会有帮助。在我的情况下,我在B和BInterface中错过了一个重要的细节:public class B : BInterface where T : AInterface { public T Element { get; set; } } public interface BInterface where T : AInterface { T Element { get; set; } }out将不起作用,因为T既在输入又在输出。有什么建议? - roger
是的,如果您在类型参数上有一个通用约束,则无法使其协变。这是按设计进行的。在泛型接口中,如果满足以下条件,可以声明类型参数为协变:1)类型参数仅用作接口方法的返回类型,而不用作方法参数的类型。2)类型参数未用作接口方法的通用约束。http://msdn.microsoft.com/en-us/library/dd469487(VS.100).aspx - Alexandra Rusina

1

我认为你漏掉了out关键字。尝试将它添加到以下行中:

public interface BInterface<out T> where T : AInterface { }
public class Z<out T> where T : BInterface<AInterface> {}

我不确定两个地方都需要它。


类不能是变体的,因此您无法在类中为通用参数添加“out”或“in”。 - Alexandra Rusina

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接