尝试将具体对象强制转换为通用接口时出现“InvalidCastException”

时间:2013-03-17 15:29:46

标签: c# .net

我正在尝试使用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
    {
    }
}

2 个答案:

答案 0 :(得分:1)

你得到的是IActionValidator<IActionSomething>。无法将IActionValidator<IActionSomething>分配给IActionValidator<IAction>,因为T被标记为in类型参数。

想象一下,对于名为IActionValidator<IAction>的{​​{1}}变量,有以下v方法:

Validate

现在,如果Validate(IAction action, out string failure); 指向v的实例,您可以通过IActionValidator<IActionSomething>IAction实例传递给第一个参数,该参数未实现v }。但是,IActionSomething确实需要后者。因此,编译器不会让你这样做。

答案 1 :(得分:0)

一种方法是使用dynamic

dynamic smth = Activator.CreateInstance(typeFromSomewhere);

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