动态动作< T> :执行时无效的参数 [英] Dynamic Action<T> : Invalid Arguments when executed

查看:114
本文介绍了动态动作< T> :执行时无效的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我正式的大小的项目中有很多地方,我需要打开一个类型。显然,我不能在.NET中做到这一点(以一种简单的方式来满足我的需求),所以我必须做一个体面的投射。这个代码是试图隐藏一些概念证明的结果。



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

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

和我的课程:

  public sealed class TypeSwitch< T> 
{
私人字典<类型,动态> _dict;

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

public TypeSwitch< T>在其中K:T
{
_dict.Add(typeof(K),action))中添加< K>(Action< K>
返回这个;
}

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


附加信息: System.Action< ConsoleApp.Derived>'有一些无效的参数


如果我可以使它工作,这将是非常光滑和有用的。有人向我解释我失踪了吗?有可能得到这个工作吗?

解决方案

尝试另一个级别的lambdas。除了工作,我预计这将比使用动态更快,即使有两个代理被调用。

  public sealed class TypeSwitch< T> 
{
私人字典< Type,Action< T>> _dict; //不再动态

public TypeSwitch()
{
_dict = new Dictionary< Type,Action< T>(); //不再动态
}

public TypeSwitch< T>其中K:T
{
_dict.Add(typeof(K),o => action((K)o));< K>(Action< K> //外lambda在调用内部lambda之前转换该值
返回此值;
}

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


I have a lot of places in my decently sized project where I need to switch on a type. Obviously I can't do that in .NET (in a way simple enough to satisfy me), so I have to do a decent amount of casting. This code is the result of trying to hide some of that in a proof of concept.

I have a simple inheritence modeled:

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

and my 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);
    }
}

and I run it with:

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);
}    

When I get to action(item) I get a RuntimeBinderException saying

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

This would be pretty slick and helpful if I could get it working. Can someone explain to me what I'm missing? Is it possible to get this working?

解决方案

Try another level of lambdas. In addition to working, I expect this would be considerably faster than using dynamic, even though there are two delegates being invoked.

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);
    }
}

这篇关于动态动作&lt; T&gt; :执行时无效的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆