使用一个字典<串,对象>作为字典<字符串,字典<字符串,字符串>>

问题描述:

在C#我需要保持数据在一个字典对象,看起来像:使用一个字典<串,对象>作为字典<字符串,字典<字符串,字符串>>

Dictionary<string, Dictionary<string, string>> MyDict = 
    new Dictionary<string, Dictionary<string, string>>(); 

现在我意识到,在某些情况下,我需要一些其他的(不是字典式的)数据作为主字典的值。

是否有任何问题或限制,如果我只是实例的主要字典。如:

Dictionary<string, object> MyDict = new Dictionary<string, object>(); 

物场我可以把字符串,字典,无论..

由于提前, 最好的问候,史蒂芬

+0

标题您的问题 – vulkanino 2012-02-08 16:12:55

+0

我不会”的文中不符我认为这将是一个问题。您可能只需要将其转换为访问它时应该使用的内容即可。 – Kevin 2012-02-08 16:13:51

+0

你可以看到这个问题的答案http://stackoverflow.com/questions/569903/multi-value-dictionary是你想要的吗? – DotNetUser 2012-02-08 16:14:31

通过使用对象为在你的字典值时,您将承担一定的风险和并发症:

  • 缺乏类型安全的(什么都可以设置为值)
  • 你将不得不转换为特定类型,可能基于值

您应该重新考虑您的设计。但是,如果你真的想要一个灵活性,你可以创建一个新的类型,作为值类型。喜欢的东西:

class MySpecialType 
{ 
    public Dictionary<string, string> MyStringDictionary { get; set; } 
    public string MyStringVal {get; set;} 

    public Type ActiveType { get; set; } // property would specify the current type 
    // ... 

你的主词典声明会再看看这样的:

Dictionary<string, MySpecialType> MyDict = new Dictionary<string, MySpecialType>(); 

您可以使用ActiveType财产或创造条件,指定类型的枚举。您也可以在类中使用静态实用功能,以帮助您返回正确的实例和类型...

+0

你的答案与其他人的知识相结合对我来说最合适。 (感谢那!) 在这种情况下,“缺少类型安全性(任何可设置的值)”对我来说都是一个特性:D 您对类的解决方案很有意义,但有点像我试图避免的开销我。 如此解决,多亏了所有,我的主要问题是代码的上下文和设计。 ***感谢*** – N471v3 2012-02-08 16:47:27

没有,有没有问题。如果你需要输入值为Dictionary<string, string>,那么只需施放它,你就能解决这个问题。

是的,你的字典里就没有强类型化了 - 你可以不喜欢第一种方法:

string value = myDict["foo"]["bar"]; 

在第二种方法,这是不可能的了,因为你要投第一:

string value = ((Dictionary<string,string>)myDict["foo"])["bar"]; 

这听起来像你的问题可以用更好的设计方法解决。通常需要通过重新设计解决方案来避免在同一数据结构中存储不同类型的对象 - 因此为什么需要这样做?

编辑:

如果你只是想处理null值,你可能只是这样做:

string value = myDict["foo"] != null ? myDict["foo"]["bar"] : null; 

或者包裹在一个扩展方法:

public static T GetValue<T>(this Dictionary<T, Dictionary<T,T>> dict, 
          T key, T subKey) where T: class 
{ 
    T value = dict[key] != null ? dict[key][subKey] : null; 
    return value; 
} 

string value = myDict.GetValue("foo", "bar"); 
+0

因为这实现了大约1000行代码,并且在某些情况下,需要使用null添加值,其中密钥用作数据。 like: MyDict.Add(“One_key”,AnotherDictionary); MyDict.Add(“Cool_key”,null); than for循环: if(MyDict.value!= null) //做某事 而你的观点是对的,设计也许有点错误!但是现在我需要数据的关键字和值域,并且认为我不想为这些具有值null的键值对生成一个子字典,因为代码开销,如果您知道我的意思。 (许多空值的条目) – N471v3 2012-02-08 16:24:58

+0

谢谢大家的快速和好回答! – N471v3 2012-02-08 16:27:40

好,你的代码会更少类型安全,你需要运行时类型检查和类型转换,否则你可以使用object作为字典值类型并存储任何类型。

你会失去强大的类型和所有的好处。

你能不能创建一个具有解释性质的新类和添加其他数据吧:

public class CallItWhatYouLike 
{ 
    public Dictionary<string, string> Dictionary {get; set;} 
    public int AnotherProperty {get; set;} 
    ... 
} 

var MyDict = new Dictionary<string, CallItWhatYouLike>(); 

你会付出性能上的损失,当你unboxSystem.Object,但除此之外,有ISN”除了索引器过度投射外(由于输入较弱,),您的方法存在问题。

如果您使用的是.NET 4,则可以考虑使用System.Tuple

您可以这样做。从主词典中检索数据后,您必须将结果强制转换为适当的类型:

object obj; 
If(mainDict.TryGetValue("key", out obj)) { 
    var dict = obj as Dictionary<string, string>>; 
    if (dict != null) { 
     // work with dict 
    } else { 
     var value = obj as MyOtherType; 
     .... 
    } 
} 

但是请注意,这不是类型安全的;即编译器只能根据object类型的值仅部分检查代码的有效性。


或者你可以尝试更多的面向对象的解决方案

public abstract class MyBaseClass 
{ 
    public abstract void DoSomething(); 
} 

public class MyDictClass : MyBaseClass 
{ 
    public readonly Dictionary<string, string> Dict = new Dictionary<string, string>(); 

    public override void DoSomething() 
    { 
     // So something with Dict 
    } 
} 

public class MyTextClass : MyBaseClass 
{ 
    public string Text { get; set; } 

    public override void DoSomething() 
    { 
     // So something with Text 
    } 
} 

然后宣布你的主词典与

var mainDict = new Dictionary<string, MyBaseClass>(); 

mainDict.Add("x", new MyDictClass()); 
mainDict.Add("y", new MyTextClass()); 

... 

MyBaseClass result = mainDict[key]; 
result.DoSomething(); // Works for dict and text!