';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
    {
    }
}

';InvalidCastException';同时尝试将具体对象强制转换为通用接口

您得到的是一个IActionValidator<IActionSomething>IActionValidator<IActionSomething>不能分配给IActionValidator<IAction>,因为T被标记为in类型参数。

想象一下,对于名为vIActionValidator<IAction>变量,有以下Validate方法:

Validate(IAction action, out string failure);

现在,如果v指向IActionValidator<IActionSomething>的实例,则可以通过不实现IActionSomethingvIAction实例传递给第一个参数。然而,IActionValidator<IActionSomething>将需要后者。因此,编译器不会允许您这样做。

一种方法是使用动态。

dynamic smth = Activator.CreateInstance(typeFromSomewhere);

您将失去自动完成功能,因为编辑器无法在设计时确定类型。但是您仍然可以通过手动编码来调用这些方法。smth.Validate(() => true, "");