C# 使用 Dictionary<string, object> 作为 Dictionary<string, Dictionary<string, string>>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9197084/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 06:19:59  来源:igfitidea点击:

Using an Dictionary<string, object> as Dictionary<string, Dictionary<string, string>>

c#objectdictionary

提问by N471v3

in C# I need to keep data in a dictionary object, looks like:

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

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

Now I realised, that I would need in some cases some other (not dictionary-like) data as value of the main dict.

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

Is there any kind of Problem or limitation, if I just instance the main dict. as:

如果我只是举例说明主要的字典,是否有任何问题或限制。作为:

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

in the object field I could put string, dictionary, whatever..

在对象字段中,我可以放置字符串、字典等等。

Thanks in advance, Best regards, Steven

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

采纳答案by Paul Sasik

By using object as the value in your dictionary you will incur some risk and complications:

通过使用 object 作为字典中的值,您将招致一些风险和并发症:

  • Lack of type safety (anything can be set to the value)
  • You would have to cast to a particular type, probably based on the value
  • 缺乏类型安全(任何值都可以设置)
  • 您必须转换为特定类型,可能基于值

You should probably rethink your design. But if you really want a the flexibility you could create a new type that would work as the value type. Something like:

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

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
    // ...

Your main dictionary declaration would then look something like:

您的主字典声明将如下所示:

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

You could use the ActiveType property or create an enum which would specify the type. You could also have static util functions in the class which could help with returning the right instance and type...

您可以使用 ActiveType 属性或创建一个枚举来指定类型。您还可以在类中使用静态 util 函数,这有助于返回正确的实例和类型...

回答by Matías Fidemraizer

No, there's no problem. If you need to type the value as Dictionary<string, string>just cast it and you'll have this solved.

不,没有问题。如果您需要输入值作为Dictionary<string, string>刚刚投射它,您将解决这个问题。

回答by BrokenGlass

Yes, your dictionary would not be strongly typed anymore - in the first approach you could do something like:

是的,您的字典将不再是强类型的 - 在第一种方法中,您可以执行以下操作:

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

In the second approach this is not possible anymore since you have to cast first:

在第二种方法中,这不再可能,因为您必须先进行转换:

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

It sounds like your problem could be solved with a better design approach. Usually the need to store different kind of objects in the same data structure can be avoided by re-designing the solution - so whydo you need to do this?

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

Edit:

编辑:

If you just want to handle nullvalues you could just do something like:

如果您只想处理null值,您可以执行以下操作:

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

Or wrapped in an extension method:

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

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

回答by wRAR

Well, your code will be less typesafe and you will need runtime type checks and type casts, but otherwise you can use objectas a dictionary value type and store any types there.

好吧,您的代码将不那么类型安全,您将需要运行时类型检查和类型转换,否则您可以将其object用作字典值类型并将任何类型存储在那里。

回答by vc 74

You'll loose strong types and all their benefits.

您将失去强类型及其所有好处。

Can you not create a new class that has a Dictionary property and add your other data to it:

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

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

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

回答by SliverNinja - MSFT

You will pay a performance penalty when you unboxthe System.Object, but other than that there isn't a problem with your approach other than excessive casting for indexers (due to weak typing).

当您将支付性能损失拆箱System.Object,但除此之外,没有比过大铸造等你的方法对索引(一个问题,由于弱类型)。

You may consider using a System.Tupleif you are using .NET 4.

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

回答by Olivier Jacot-Descombes

You can do that. After retrieving data from the main dictionary, you will have to cast the result to an appropriate type:

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

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

But note that this is not type-safe; i.e., the compiler can only partially check the validity of your code regarding the values of type object.

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



Alternatively you could try a more object-oriented solution

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

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

Then declare your main dictionary with

然后声明你的主字典

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!