';InvalidCastException';同时尝试将具体对象强制转换为通用接口
本文关键字:转换 接口 对象 InvalidCastException | 更新日期: 2023-09-27 18:04:14
我正试图使用Activator.CreateInstance创建一个类,并将其强制转换为它实现的通用接口。
为什么我在运行时(.Net 4.0(得到"InvalidCastException"?
这是代码:
namespace CastingGenerics
{
class Program
{
static void Main(string[] args)
{
var typeFromSomewhere = typeof(ActionSomethingValidator);
// This line throw 'System.InvalidCastException'
// "Unable to cast object of type 'CastingGenerics.ActionSomethingValidator' to type 'CastingGenerics.IActionValidator`1[CastingGenerics.IAction]'."
var castingError = (IActionValidator<IAction>)Activator.CreateInstance(typeFromSomewhere);
}
}
internal interface IAction
{
}
internal interface IActionValidator<in T>
where T : IAction
{
bool Validate(T action, out string failure);
}
internal abstract class ActionValidator<T> : IActionValidator<T>
where T : IAction
{
public abstract bool Validate(T action, out string failure);
}
internal class ActionSomethingValidator : ActionValidator<IActionSomething>
{
public override bool Validate(IActionSomething action, out string failure)
{
failure = string.Empty;
return true;
}
}
internal interface IActionSomething : IAction
{
}
}
您得到的是一个IActionValidator<IActionSomething>
。IActionValidator<IActionSomething>
不能分配给IActionValidator<IAction>
,因为T
被标记为in
类型参数。
想象一下,对于名为v
的IActionValidator<IAction>
变量,有以下Validate
方法:
Validate(IAction action, out string failure);
现在,如果v
指向IActionValidator<IActionSomething>
的实例,则可以通过不实现IActionSomething
的v
将IAction
实例传递给第一个参数。然而,IActionValidator<IActionSomething>
将需要后者。因此,编译器不会允许您这样做。
一种方法是使用动态。
dynamic smth = Activator.CreateInstance(typeFromSomewhere);
您将失去自动完成功能,因为编辑器无法在设计时确定类型。但是您仍然可以通过手动编码来调用这些方法。smth.Validate(() => true, "");