Jon*_*lis 4 c# generics types dynamic
我在规模很大的项目中有很多地方需要打开一个类型.显然我不能在.NET中做到这一点(以一种简单到足以满足我的方式),所以我必须进行相当数量的转换.此代码是试图在概念证明中隐藏其中一些内容的结果.
我有一个简单的继承模型:
public class Base { }
public class Derived : Base { public string Name { get; set; } }
Run Code Online (Sandbox Code Playgroud)
和我的班级:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我运行它:
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);
}
Run Code Online (Sandbox Code Playgroud)
当我到达时,action(item)我得到一个RuntimeBinderException说法
附加信息:委托'System.Action <ConsoleApp.Derived>'有一些无效的参数
如果我可以使它工作,这将是非常光滑和有用的.有人可以向我解释我错过了什么吗?有可能让这个工作吗?
小智 6
你的item参数不是dynamic.因为它是静态类型的T,所以该类型T(恰好是Base)将用于重载解析.Action<Derived>不能用Base参数调用.
要dynamic在这里使用,你也需要做item dynamic:action(item);改为action((dynamic) item);.
尝试另一个级别的lambdas.除了工作之外,我预计这会比使用快得多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);
}
}
Run Code Online (Sandbox Code Playgroud)