ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

强制转换为具有接口的泛型类

2019-10-28 20:17:07  阅读:169  来源: 互联网

标签:generics covariance c


更新了MarcinJuraszek的输入

我有一种感觉,我在碰到一个co /相反方差问题,但是我不确定我是否知道如何解决它.我有这样的课:

public interface ISomeClass<TEnum, out S>
{
     TEnum Dim { get; }
     IEnumerable<S> Inc { get; }
}

public class SomeClass<TEnum, S> : ISomeClass<TEnum, S>
    where TEnum : struct, IConvertible
    where S : IMyInterface
{
    public TEnum Dim { get; set; }
    public IEnumerable<S> Inc { get; set; }
}

我有一个实现IMyInterface的类

public class MyImplementation : IMyInterface
{

}

而且,当然,我有一个带有SomeClass属性的类:

public class MyContainer<TEnum> where TEnum : struct, IConvertible
{
    public SomeClass<TEnum, IMyInterface> MyProp { get; set; }
}

现在我的问题是我不能分配SomeClass< MyEnum,MyImplementation>设置为MyProp属性,因为在运行时我收到InvalidCastException,抱怨它无法转换SomeClass< MyEnum,MyImplementation>.到SomeClass< MyEnum,IMyInterface>.

我该如何解决?

例如,这不能编译:

var c = new MyContainer<MyEnum>();
c.MyProp = new SomeClass<MyEnum, MyImplementation>();

这是一个dot net fiddle

解决方法:

您可以通过使通用类型参数不变(协变或反变,取决于其成员)来使其工作.但是,在C#中,您只能在接口上声明通用参数不变,因此您必须声明另一个接口:

public interface ISomeClass<TEnum, in S>
{

}

public class SomeClass<TEnum, S> : ISomeClass<TEnum, IMyInterface>
    where TEnum : struct, IConvertible
    where S : IMyInterface
{

}

public class MyContainer<TEnum> where TEnum : struct, IConvertible
{
    public ISomeClass<TEnum, IMyInterface> MyProp { get; set; }
}

这将使以下代码编译:

var container = new MyContainer<DayOfWeek>();
container.MyProp = new SomeClass<DayOfWeek, MyImplementation>();

另一个可能的解决方案是使用另一个接口,其中不存在S泛型类型参数:

public interface ISomeClass<TEnum>
    where TEnum: struct, IConvertible
{

}

public class SomeClass<TEnum, S> : ISomeClass<TEnum>
    where TEnum : struct, IConvertible
    where S : IMyInterface
{

}

public class MyContainer<TEnum> where TEnum : struct, IConvertible
{
    public ISomeClass<TEnum> MyProp { get; set; }
}

奖金-为何不起作用:

假设您的代码可以编译,并且您可以分配MyClass< T>到MyClass< IT>只要T实施IT.您可以参加以下课程:

class MyClass<T>
{
    public List<T> MyProp { get; set; }
}

然后做

MyClass<IMyInterface> instance = new MyClass<MyInterfaceImplementation>();

MyProp将是List< MyInterfaceImplementation>.但您可以像使用List< IMyInterface>因此您可以尝试添加MyOtherInterfaceImplementation元素,该元素在运行时会崩溃.不好玩.

标签:generics,covariance,c
来源: https://codeday.me/bug/20191028/1955013.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有