使用Dictionary <string,object =“”>作为Dictionary <string,dictionary <string,=“”string =“”>&gt; </string,> </string,>

时间:2012-02-08 16:10:43

标签: c# object dictionary

在C#中我需要将数据保存在字典对象中,如下所示:

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

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

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

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

在对象字段中我可以放字符串,字典,等等..

提前致谢, 最诚挚的问候,史蒂文

7 个答案:

答案 0 :(得分:5)

是的,你的字典不再是强类型了 - 在第一种方法中你可以做类似的事情:

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

答案 1 :(得分:4)

你可以做到这一点。从主字典中检索数据后,您必须将结果转换为适当的类型:

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!

答案 2 :(得分:1)

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

您是否可以创建一个具有Dictionary属性并将其他数据添加到其中的新类:

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

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

答案 3 :(得分:1)

通过使用对象作为词典中的值,您将面临一些风险和复杂性:

  • 缺乏类型安全(任何东西都可以设置为值)
  • 您可能需要转换为特定类型,可能基于值

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

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属性或创建指定类型的枚举。您还可以在类中使用静态util函数,这有助于返回正确的实例并键入...

答案 4 :(得分:0)

不,没问题。如果您需要将值键入为Dictionary<string, string>,只需将其投射,您就可以解决此问题。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

当您System.Object {{1}}时,您将支付性能损失,但除了针对索引器的过度投射之外,您的方法没有问题(由于打字不足)。

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