.NET 4.0 Cast 通用接口(interface)

标签 .net generics interface casting

我有两个接口(interface),其中一个是通用接口(interface),只允许从第二个接口(interface)派生的类型。它们看起来像这样:

public interface IProvider<T> where T : IContent
{
    T getContent(int i);
    void addContent(T content);
}
public interface IContent
{
    string whatIAm();
}

当然,我的真实接口(interface)更复杂,但足以说明我的问题是什么。
现在我为每个接口(interface)都有一个具体的类:
public class Provider : IProvider<FileContent> 
{
    public FileContent getContent(int i)
    {
        return null;
    }
    public void addContent(FileContent content)
    {
    }
}

public class FileContent : IContent{
    public string whatIAm(){
        return "FileContent";
    }
}

在我的代码中,我想使用引用类型“IProvider”,但转换出错了......请看这个例子:
 static void Main(string[] args)
    {
        Provider p = new Provider(); //works
        IProvider<FileContent> pp = p as IProvider<FileContent>; //also works
        IProvider<IContent> ppp = pp as IProvider<IContent>; //fails :(
    }
ppp始终为空。我必须改变这个 Actor 阵容的工作吗?
提前致谢。

最佳答案

类型参数必须完全匹配。 IProvider<IContent>是与 IProvider<FileContent> 不同的类型,它们之间没有继承关系。

想象一下,您有一个 IProvider<IContent> ppp来自您的IProvider<FileContent>开发人员尝试 ppp.addContent(someOtherContentThatIsNoFileContent) .该声明适用于 IProvider<IContent> ,但它会破坏类型安全,因此不允许这样的转换是正确的做法。

Covariance and Contravariance for generic type parameters在某些情况下允许这样的事情,但是由于您的接口(interface)使用类型参数作为输入参数和输出参数,这不适用于它现在声明的方式。

编辑:IEnumerable的定义:

public interface IEnumerable<out T> 

所以你知道 IEnumerable 使用 T仅作为输出参数(您不能添加项目,只能枚举它们),以及 out关键字指定 T是协变的。所以你可以做
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;

如果你想这样做,你必须删除 add从您的界面中获取方法。同样适用于输入参数和 in泛型类型参数的关键字。

您的界面将如下所示:
public interface IProvider<out T> where T : IContent
{
    T getContent(int i);
}

关于.NET 4.0 Cast 通用接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11522420/

相关文章:

c# - 隐式运算符?

c++ - 当 List<List<X>> 时,模板在 C++ 中删除

java - 接口(interface)类型的变量

typescript - 在这种情况下,为什么不从参数推断出通用值 N ?

java - 如何扩展抽象泛型抽象接口(interface)?

c++ - C++中的接口(interface)设计和继承

c# - 使用 ClrMD 附加到自身?结果 : 0x80070057

c# - 将任何日期时间值转换为 UTC

.net - 使用Rfc2898DeriveBytes类获取Key和IV

java - 有没有办法强制 Arrays.asList 的返回类型