我想创建一个要在绘图对象上执行的操作列表。以下是非通用代码的样子:
private Dictionary<String, Action<Drawing, String>> actions = new Dictionary<String, Action<Drawing, String>>();
private void LoadActions()
{
actions.Add("Height", (d, s) => d.Height = Double.Parse(s));
actions.Add("Width", (d, s) => d.Width = Double.Parse(s));
}
private void ProcessDrawing(Drawing drawing, String prop, String value)
{
actions[prop](drawing, value);
}
我遇到的问题是Drawing类是通用类(Drawing<T>
)因此我无法定义如下所示的操作,因为未定义T:
Dictionary<String, Action<Drawing<T>, String>> actions = new Dictionary<String, Action<Drawing<T>, String>>();
没有缓存,代码如下所示:
private void ProcessDrawing<T>(Drawing<T> drawing, String prop, String value)
{
var actions = new Dictionary<String, Action<Drawing<T>, String>>();
actions.Add("Height", (d, s) => d.Height = Double.Parse(s));
actions.Add("Width", (d, s) => d.Width = Double.Parse(s));
actions[prop](drawing, value);
}
那么如何缓存一系列接受泛型参数的动作呢?
谢谢,
答案 0 :(得分:1)
所有操作的基类都是MulticastDelegate
。您必须将您的字典定义为Dictionary<String,MulticastDelegate>
,并在从字典中检索您的操作后使用适当的演员。
修改强>:
测试表明,lambda表达式显然不能直接分配给MulticastDelegate
类型的变量。这是因为lambda表达式参数的类型是从它所分配的变量(或方法参数)的类型推断出来的。因此,首先将其分配给具有正确Action<>
类型的变量。然后将其分配给MulticastDelegate
。
在示例中,我显示了两个版本(通过方法参数和变量):
public static void CallTestDelegate()
{
TestDelegate((d, s) => d.Height = Single.Parse(s));
}
public static void TestDelegate(Action<RectangleF, string> action)
{
Dictionary<String, MulticastDelegate> dict = new Dictionary<string, MulticastDelegate>();
dict.Add("a1", action);
Action<RectangleF, string> action2 = (d, s) => d.Width = Single.Parse(s);
dict.Add("a2", action2);
var a1 = (Action<RectangleF, string>)dict["a1"];
a1(new RectangleF(), "15");
}
答案 1 :(得分:0)
一个选项是使Drawing<T>
派生自具有IDrawing
和Height
属性的非通用接口Width
,然后将您的操作更改为{{1}类型1}}。
另一个选项(类型安全性较低)是将您的操作设为Action<IDrawing,String>
。
答案 2 :(得分:0)
T只是一个占位符,创建一个表示你想要的对象的抽象类或接口