首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >铸造泛型和泛型

铸造泛型和泛型
EN

Stack Overflow用户
提问于 2010-04-19 23:54:04
回答 2查看 547关注 0票数 6

考虑一下,我有以下3个类/接口:

代码语言:javascript
运行
复制
class MyClass<T> { }

interface IMyInterface { }

class Derived : IMyInterface { }

我希望能够将MyClass<Derived>转换为MyClass<IMyInterface>或visa--相反:

代码语言:javascript
运行
复制
MyClass<Derived> a = new MyClass<Derived>();
MyClass<IMyInterface> b = (MyClass<IMyInterface>)a;

但是,如果我尝试:

代码语言:javascript
运行
复制
Cannot convert type 'MyClass<Derived>' to 'MyClass<IMyInterface>'   

我肯定有一个很好的理由我不能这样做,但我想不出一个。

至于我为什么要这样做--我想象的场景是,您理想上希望使用MyClass<Derived>实例,以避免大量讨厌的强制转换,但是您需要将实例传递给接受MyClass<IMyInterface>的接口。

所以我的问题有两个:

  • 为什么不能在这两种类型之间进行转换呢?
  • 是否可以在仍然能够将其转换为一个MyClass<Derived>实例的同时保持使用MyClass<Derived>实例的良好性能呢?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-04-19 23:56:25

这不起作用,因为C#只支持接口和委托的类型参数的协方差。如果您的类型参数只存在于输出位置(即您只从类返回它的实例,而不接受它作为参数),则可以创建如下接口:

代码语言:javascript
运行
复制
interface IClass<out T> { }
class MyClass<T> : IClass<T> { }

这样你就可以这样做:

代码语言:javascript
运行
复制
IClass<Derived> a = new MyClass<Derived>();
IClass<IMyInterface> b = a;

老实说,这几乎是你将要得到的,这需要C# 4编译器才能工作。

票数 5
EN

Stack Overflow用户

发布于 2010-04-20 00:12:57

一般情况下,您不能这样做的原因是因为大多数类不是简单的空示例。它们有以下方法:

代码语言:javascript
运行
复制
class MyClass<T> 
{
    static T _storage;

    public void DoSomethingWith(T obj)
    {
        _storage = obj;
    }
}

interface IMyInterface { }

class Derived : IMyInterface { }

MyClass<Derived> a = new MyClass<Derived>();

现在,a有一个方法DoSomethingWith,它接受Derived并将其存储在类型为Derived的静态变量中。

代码语言:javascript
运行
复制
MyClass<IMyInterface> b = (MyClass<IMyInterface>)a;

如果允许的话,b现在看起来有一个方法DoSomethingWith,它接受任何实现IMyInterface的东西,然后在内部尝试将它存储在一个Derived类型的静态变量中,因为它仍然是a所引用的同一个对象。

所以现在您有一个Derived类型的变量存储..。谁知道呢。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2671676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档