gpt4 book ai didi

C# 泛型、接口(interface)和继承

转载 作者:太空狗 更新时间:2023-10-29 20:54:07 25 4
gpt4 key购买 nike

我有两个接口(interface):

public interface IAmA
{
}

public interface IAmB<T> where T : IAmA
{
}

还有两个像这样实现这些接口(interface)的类:

public class ClassA : IAmA
{
}

public class ClassB : IAmB<ClassA>
{
}

当尝试使用这些类时:

public class Foo
{
public void Bar()
{
var list = new List<IAmB<IAmA>>();
list.Add(new ClassB());
}
}

我得到这个编译器错误:

cannot convert from 'ClassB' to 'IAmB<IAmA>'

我知道我可以让编译器高兴地使用:

public class ClassB : IAmB<IAmA>
{
}

但我需要能够成为 IAmB<> 的类型参数在 ClassB IAmA 的实现.

最佳答案

快速的回答是你可以通过声明 IAmB<T> 的类型参数来做你要求的事情。作为协变,仅当类型用作返回类型时:

public interface IAmB<out T> where T : IAmA
{
T SomeMethod(string someparam);
}

out T意味着您可以使用比约束中指定的类型更具体的类型。

您将无法使用 T 作为参数。以下将无法编译:

public interface IAmB<out T> where T : IAmA
{
void SomeMethod(T someparam);
}

来自文档

You can use a covariant type parameter as the return value of a method that belongs to an interface, or as the return type of a delegate. You cannot use a covariant type parameter as a generic type constraint for interface methods.

这不是编译器的怪癖。假设您可以声明一个协变方法参数,您的列表最终将包含一些无法处理 IAmB<IAmA> 的对象。参数——他们期望输入 ClassA 或更具体的。您的代码可以编译但在运行时失败。

这引出了一个问题 - 为什么要使用 IAmB<ClassA>

虽然您应该在使用它之前考虑一下,因为可能有其他更合适的方法来解决您的实际问题。使用实现具体类型的通用接口(interface),但试图将它当作实现另一个接口(interface)来使用是不寻常的。

您可以在 Covariance and Contravariance 上查看 MSDN 文档部分以及 Eric Lippert 和 Jon Skeet 对 this SO question: Difference between Covariance and Contravariance 的回答

关于C# 泛型、接口(interface)和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32495510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com