【问题标题】:Creating Dictionary C# with custom type passed by function使用函数传递的自定义类型创建字典 C#
【发布时间】:2012-09-21 17:53:33
【问题描述】:

我想创建一个字典,其中 TKey 作为字符串,TValue 来自编译时不知道的类型。

比如说我有一个函数

 createDict(Type type)
 {
     Dictionary<string, {here's the type from the func. argument}> dict = new Dictionary..

 }

这种情况是可能的还是我错过了一些非常基本的东西?

【问题讨论】:

  • 您的类型是如何确定的?人们似乎在支持泛型解决方案,而不考虑您在编译时不知道类型的声明(在编译时没有反射需要类型的封闭泛型)。如果您可以向我们展示如何确定类型,则可以更好地针对您的问题量身定制答案。
  • 在我看来,类型是由传递给 createDict() 的“Type”参数确定的
  • @MatthewWatson 显然,但我试图确定它是否真的需要,而不是在编译时知道类型。面对Dictionary&lt;string, object&gt; 甚至Hashtable,反映一个你不知道类型的通用字典对我来说似乎很奇怪。
  • 是的,有点奇怪。实际上使用创建的字典也不会很简单!

标签: c# dictionary


【解决方案1】:

如果将类型作为参数传递就可以做到:

var dictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string),type);
var dictionary = (IDictionary)Activator.CreateInstance(dictionaryType);

由于您对插入到该字典的内容的正确性负全部责任,因此使用此类字典将更加困难。

【讨论】:

    【解决方案2】:

    使方法通用:

    public void CreateDict<T>()
    {
        Dictionary<string,T> dict = new Dictionary<string,T>();
    
    }
    

    虽然您可能希望返回类型也为 Dictionary&lt;string,T&gt; 并为泛型类型参数添加约束。

    你可以这样称呼它:

    CreateDict<MyCustomType>();
    

    以上假设类型可以在编译时传入。

    【讨论】:

    • 请注意 - 这假设类型在编译时是已知的(从调用者的角度来看)。
    【解决方案3】:

    你可以做一点反思:

    Type dict = typeof (Dictionary<,>);
    Type[] parameters = {typeof (string), type};
    Type parametrizedDict = dict.MakeGenericType(parameters);
    object result = Activator.CreateInstance(parametrizedDict);
    

    【讨论】:

    • @Oded OP 声明“在编译时未知”,但没有关于如何确定类型的任何细节,没有人知道反射或泛型是否合适。
    • @Oded,是吗?我一定遗漏了一些东西,但是帖子作者说 在编译时不知道的类型
    • 在该代码中,您应该只使用 'type' 而不是 'typeof(type)',不是吗? (即只使用传递给 OP 的 createDict() 方法的“类型”参数)
    【解决方案4】:

    所有的实例和类都是对象,所以为什么不 Dictionary&lt;string,object&gt; 并且你确实像在 MVC、Session 或 Cache 中使用 ViewData 一样进行转换,它们都需要转换。

    【讨论】:

      【解决方案5】:

      如果类型在编译时已知,则使用泛型:

      void Main()
      {
          var dict = CreateDict<int>();
          dict["key"] = 10;
      }
      
      Dictionary<string, T> CreateDict<T>()
      {
          return new Dictionary<string, T>();
      }
      

      如果不是,请重构以使用基本类型或接口,例如:

      var dic = new Dictionary<string, IMyType>();
      

      其中 IMyType 公开了您希望保留在字典中的类型的共同特征。

      只有在万不得已的情况下,我才会考虑反思。

      【讨论】:

      • 请注意 - 这假设类型在编译时是已知的(从调用者的角度来看)。
      • 没错。如果在编译时类型未知,我想要走的路是反射。通常,尽管这是一个有问题的设计的标志。我编辑了我的帖子以反映这一点
      猜你喜欢
      • 1970-01-01
      • 2015-08-17
      • 2016-08-03
      • 1970-01-01
      • 2022-07-27
      • 2011-08-06
      • 2019-08-21
      • 2023-03-20
      • 1970-01-01
      相关资源
      最近更新 更多