C#模式缓存接受通用参数的操作

时间:2011-12-08 20:41:27

标签: c# design-patterns .net-3.5

我想创建一个要在绘图对象上执行的操作列表。以下是非通用代码的样子:

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

那么如何缓存一系列接受泛型参数的动作呢?

谢谢,

3 个答案:

答案 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>派生自具有IDrawingHeight属性的非通用接口Width,然后将您的操作更改为{{1}类型1}}。

另一个选项(类型安全性较低)是将您的操作设为Action<IDrawing,String>

答案 2 :(得分:0)

T只是一个占位符,创建一个表示你想要的对象的抽象类或接口