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)
归档时间: |
|
查看次数: |
206 次 |
最近记录: |