动态动作<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);
。
我的项目中有很多地方需要打开类型。显然我不能在 .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);
。