c# - 泛型类型转换异常
问题描述
public interface IRule <T>
{
T Execute();
}
public class Rule : IRule<int>
{
public int Execute()
{
return 10;
}
}
IRule<int> rule = new Rule();
var genericRule = (IRule<object>) rule;
//Exception has occurred: CLR/System.InvalidCastException An exception of ype 'System.InvalidCastException' occurred in test.dll but was not handled in user code: 'Unable to cast object of type 'test.GenericCasting.Rule' to type test.GenericCasting.IRule`1[System.Object]'.'
在业务逻辑中,我需要通过反射加载所有规则对象,并且不知道规则对象中使用的类型。知道如何解决这个问题吗?
解决方案
为了在您的示例中执行类型转换,必须满足两个条件:
IRule<T>
必须是协变的,也就是说,IRule<out T>
- 协方差仅适用于引用类型 as
T
,也就是说,您不能使用int
forT
,但可以使用string
for 。
一个工作示例:
public interface IRule <out T>
{
T Execute();
}
public class Rule : IRule<string> // T must be a reference type
{
public string Execute()
{
return "10";
}
}
//....
IRule<string> rule = new Rule();
var genericRule = (IRule<object>) rule;
编辑
正如@Servy 正确提到的,我解释了为什么原始代码不起作用,但我没有解释如何解决原始问题。
方法如下:
// define a separate interface for non-typed invocation
public interface IRule
{
object ExecuteGeneric();
}
public interface IRule<T> : IRule
{
T Execute();
}
// every rule implements both typed and non-typed invocation interface
public class Rule : IRule<int>
{
public int Execute()
{
return 10;
}
object IRule.ExecuteGeneric()
{
return Execute();
}
}
//.....
IRule<int> rule = new Rule();
IRule genericRule = rule;
// perform non-typed invocation on rules of any T
var genericResult = genericRule.ExecuteGeneric();
推荐阅读
- sql - 在 PostgresSQL 中为在 SQL Server 中工作的查询创建视图(两个 DATETIME 列/TIMECODE 之间的 COUNT
- reactjs - 我如何使用 reactspring 更改和动画 div 背景图像
- asp.net - foreach 中的调用服务会减慢 Asp.Net Core 3 的速度吗?
- c# - 错误 NETSDK1100:需要 Windows 才能构建 Windows 桌面应用程序
- javascript - 闪屏前的白屏反应本机
- python - 如何在双曲python包中重新缩放瓷砖
- python - 根据同一组中位于下一行中的值删除行 | 熊猫
- r - 如何以一个假人为条件有效地重新编码一组假人?
- freeswitch - Play_and_get_digits Freeswitch 中无输入与错误输入
- javascript - 如何通过在 reactJS 的循环中重复组件特定时间来创建 2D 网格?