使用值作为Action <t>?</t>的实例创建Dictionary的语法是什么

时间:2009-04-30 06:53:57

标签: c# generics

我需要创建一个Dictionary对象作为成员字段
key =字符串
value = Action<T>的实例,其中每个条目的T可以不同,例如long,int,string(ValueType或RefType)

然而,无法让编译器在这里同意我。要创建一个成员字段,它似乎需要一个固定的T规范。在认识到“这不应该是这么困难”之前,我已经超越了奋斗时间的限制

可能是一个普通的菜鸟错误。请指教..

用法就是这样的

m_Map.Add("Key1", 
   new delegate(long l) {Console.Writeline("Woohoo !{0}", l.ToString();));

2 个答案:

答案 0 :(得分:2)

基本上,你不能。编译器如何知道您对任何特定条目感兴趣的类型?

你甚至无法解释Dictionary<Type, Action<T>>的关系,其中每个词典条目都有一个类型的键和一个使用该类型的动作。泛型只是不支持这种关系。

如果 在您尝试使用它时知道该类型,您可以将其设为Dictionary<string, Delegate>并在获取时转换该值。或者,您可以使用Action<object>并与拳击一起生活并投射你最终的结果。

请注意,要使用只有Delegate的匿名方法或lambda表达式,您需要强制转换或编写一个方便的转换方法:

public static Delegate ConvertAction<T>(Action<T> action)
{
    return action;
} 

你可以这样写:

Delegate dlg = ConvertAction((long x) => Console.WriteLine("Got {0}", x));

或在字典上下文中:

var dict = new Dictionary<string, Delegate>();
dict["Key1"] = ConvertAction((long x) => Console.WriteLine("Got {0}", x));

当您再次从字典中取出值时,仍然需要转换为正确的类型...

一个不同的方法......

您可以将字典封装在您自己的类型中,并使用通用的Add方法,而不是直接公开字典:

public void Add<T>(string key, Action<T> action)

所以它在幕后仍然是Dictionary<string, Delegate>,但你的类型会确保它只包含代表一个参数的值。

答案 1 :(得分:1)

每个条目使用不同的T,可能会在Action<object>标准化,并在实际操作中投射?

    static void Main() {
        var m_Map = new Dictionary<string, Action<object>>();
        m_Map.Add("Key1", obj => Console.WriteLine("Woohoo !{0}", obj));
        m_Map.Add("Key2", obj => SomeMethod((int)obj));

        m_Map["Key1"](123);
        m_Map["Key2"](123);
    }
    static void SomeMethod(int i) {
        Console.WriteLine("SomeMethod: {0}", i);
    }