动态动作<T>:执行时参数无效

Dynamic Action<T> : Invalid Arguments when executed

我的项目中有很多地方需要打开类型。显然我不能在 .NET 中做到这一点(以一种足够简单的方式来满足我),所以我必须进行大量的转换。此代码是试图在概念验证中隐藏其中一些内容的结果。

我有一个简单的继承模型:

public class Base { }
public class Derived : Base { public string Name { get; set; } }

和我的 class:

public sealed class TypeSwitch<T> 
{
    private Dictionary<Type, dynamic> _dict;

    public TypeSwitch()
    {
        _dict = new Dictionary<Type, dynamic>();
    }

    public TypeSwitch<T> Add<K>(Action<K> action) where K : T
    {
        _dict.Add(typeof(K), action);
        return this;
    } 

    public void Execute(T item)
    {
        var type = item.GetType();
        var action = _dict[type];

        action(item);
    }
}

我 运行 它与:

static void Main(string[] args)
{
    var ts = new TypeSwitch<Base>();
    ts.Add<Derived>(d => { Console.WriteLine(d.Name); });

    Base b = new Derived { Name = "Jonesopolis" };
    ts.Execute(b);
}    

当我到达 action(item) 时,我得到一个 RuntimeBinderException

Additional information: Delegate 'System.Action<ConsoleApp.Derived>' has some invalid arguments

如果我能让它工作的话,这将是非常巧妙和有用的。有人可以向我解释我所缺少的吗?有可能让它工作吗?

尝试另一个级别的 lambda。除了工作之外,我预计这会比使用 dynamic 快得多,即使有两个委托被调用。

public sealed class TypeSwitch<T>
{
    private Dictionary<Type, Action<T>> _dict; // no longer dynamic

    public TypeSwitch()
    {
        _dict = new Dictionary<Type, Action<T>>();  // no longer dynamic
    }

    public TypeSwitch<T> Add<K>(Action<K> action) where K : T
    {
        _dict.Add(typeof (K), o => action((K) o)); // outer lambda casts the value before calling the inner lambda
        return this;
    }

    public void Execute(T item)
    {
        var type = item.GetType();
        var action = _dict[type];
        action(item);
    }
}

您的 item 参数不是 dynamic。因为它的静态类型为 T,所以类型 T(恰好是 Base)将用于重载解析。 Action<Derived> 不能用 Base 参数调用。

要在此处使用dynamic,您还需要使item dynamic:将action(item);更改为action((dynamic) item);