Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NET中的嵌套字典集合_C#_.net_Collections_Dictionary - Fatal编程技术网

C# NET中的嵌套字典集合

C# NET中的嵌套字典集合,c#,.net,collections,dictionary,C#,.net,Collections,Dictionary,.NETDictionary对象允许分配键/值,如下所示: Dictionary<string, string> dict = new Dictionary<string, string>(); dict["1"] = "foo"; dict["2"] = "bar"; 以及一个可以多次使用密钥的实现 dict["F1"]["F2"]["F3"] = "foo"; dict["F1"]["F2"]["F3"] = "bar"; //result can be "foo"

.NET
Dictionary
对象允许分配键/值,如下所示:

Dictionary<string, string> dict = new Dictionary<string, string>();
dict["1"] = "foo";
dict["2"] = "bar";
以及一个可以多次使用密钥的实现

dict["F1"]["F2"]["F3"] = "foo";
dict["F1"]["F2"]["F3"] = "bar"; //result can be "foo" and "bar"
这可能吗

编辑(根据Jon Skeet的问题):

我想使用这样的结构(作为一个非常粗略的示例):

决心

{ data: { request: { name: "username", pass: "password" } } }

同样,XML等也会有一个等价物。

您可以使用标准字典来实现这一点,您只需声明嵌套:

Dictionary<string, Dictionary<string, string>> dict = ...
string test = dict["first"]["second"]

Dictionary<string, Dictionary<string, Dictionary<string, string>>> dict = ...
string test = dict["first"]["second"]["third"]

etc
Dictionary dict=。。。
字符串测试=dict[“第一”][“第二”]
字典dict=。。。
字符串测试=dict[“第一”][“第二”][“第三”]
等

使用
字典作为
TValue

var dict2 = new Dictionary<string, Dictionary<string, string>>();
var dict3 = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
var dict2=新字典();
var dict3=新字典();
例如:

var dict =
    new Dictionary<string, Dictionary<string, string>>
        {
            {
                "F1", new Dictionary<string, string>
                            {
                                {"F2", "foo"}
                            }
                }
        };


dict["F1"]["F2"] = "bar";
var-dict=
新词典
{
{
新词典“F1”
{
{“F2”,“foo”}
}
}
};
dict[“F1”][“F2”]=“条形”;

您必须决定要么支持固定数量的字符串键进行查找,要么提供更通用的键机制(如果键的数量可能不同)。对于第一种情况,请尝试以下操作:

Dictionary<string,Dictionary<string,string>> dict =
    Dictionary<string,Dictionary<string,string>>();
dict["F1"]["F2"] = "foo";
Dictionary<string,Dictionary<string,Dictionary<string,string>>> dict2 =
    Dictionary<string,Dictionary<string,string>>();
dict2["F1"]["F2"]["F3"] = "bar";
Dictionary<string[],string> dict = new Dictionary<string[],string>(new MyEqualityComparer());
dict[new string[] {"F1","F2"}] = "foo";
dict[new string[] {"F1","F2","F3"}] = "bar";
Dictionary dict=
字典();
dict[“F1”][“F2”]=“foo”;
字典格言2=
字典();
dict2[“F1”][“F2”][“F3”]=“条形”;
对于第二种情况,您可以执行以下操作:

Dictionary<string,Dictionary<string,string>> dict =
    Dictionary<string,Dictionary<string,string>>();
dict["F1"]["F2"] = "foo";
Dictionary<string,Dictionary<string,Dictionary<string,string>>> dict2 =
    Dictionary<string,Dictionary<string,string>>();
dict2["F1"]["F2"]["F3"] = "bar";
Dictionary<string[],string> dict = new Dictionary<string[],string>(new MyEqualityComparer());
dict[new string[] {"F1","F2"}] = "foo";
dict[new string[] {"F1","F2","F3"}] = "bar";
Dictionary dict=newdictionary(new MyEqualityComparer());
dict[newstring[]{“F1”,“F2”}]=“foo”;
dict[新字符串[]{“F1”、“F2”、“F3”}]=“bar”;
其中MyQualityComparer类类似于:

public class MyEqualityComparer : IEqualityComparer<string[]>
{
    public int GetHashCode(string[]item)
    {
         int hashcode = 0;
         foreach (string s in item)
         { 
             hashcode |= s.GetHashCode();
         }
         return hashcode;
    }

    public bool Equals(string [] a, string [] b)
    {
         if (a.Length != b.Length)
             return false;
         for (int i = 0; i < a.Length; ++i)
         {
             if (a[i] != b[i])
                 return false;
         }
         return true;
   }
公共类MyEqualityComparer:IEqualityComparer
{
public int GetHashCode(字符串[]项)
{
int hashcode=0;
foreach(项中的字符串s)
{ 
hashcode |=s.GetHashCode();
}
返回哈希码;
}
公共布尔等于(字符串[]a,字符串[]b)
{
如果(a.长度!=b.长度)
返回false;
对于(int i=0;i
我认为,您的案例是使用
DynamicObject
的好地方。我将在内部使用
字典创建一个json示例

同样的想法也可以用于xml

string json = @"{""Name"":""Joe"",
                 ""Age"":30,
                 ""Address"":{ ""City"":""NY"" }}";

dynamic dynObj = new DynamicJson(json);

Console.WriteLine(dynObj.Name);
Console.WriteLine(dynObj.Age);
Console.WriteLine(dynObj.Address.City);
--

公共类DynamicJson:DynamicObject
{
词典;
公共动态json(字符串json)
{
_Dict=(字典)新JavaScriptSerializer().DeserializeObject(json);
}
DynamicJson(Dictionary dict)
{
_Dict=Dict;
}
公共重写bool TryGetMember(GetMemberBinder绑定器,输出对象结果)
{
结果=空;
对象对象对象;
如果(!_Dict.TryGetValue(binder.Name,out obj))返回false;
if(obj是字典)
{
结果=新的DynamicJson((字典)obj);
}否则
{
结果=obj;
}
返回true;
}
}

由于需要任意长的嵌套,我提出了以下解决方案,根据我的测试,就我所知,该解决方案不会中断:

public class NestedDictionary<K, V> : Dictionary<K, NestedDictionary<K, V>>
    {
        public V Value { set; get; }

        public new NestedDictionary<K, V> this[K key]
        {
            set { base[key] = value; }

            get
            {
                if (!base.Keys.Contains<K>(key))
                {
                    base[key] = new NestedDictionary<K, V>();
                }
                return base[key];
            }
        }
    }
公共类嵌套字典:字典
{
公共V值{set;get;}
公共新嵌套字典本[K键]
{
set{base[key]=value;}
得到
{
如果(!base.Keys.Contains(key))
{
base[key]=新的嵌套字典();
}
返回基[键];
}
}
}
测试:

NestedDictionary<string, string> dict = new NestedDictionary<string, string>();
dict["one"].Value = "Nest level 1";
dict["one"]["two"]["three"].Value = "Nest level 3";
dict["FieldA"]["FieldB"].Value = "Hello World";

Console.WriteLine(dict["one"].Value);
Console.WriteLine(dict["one"]["two"]["three"].Value);
Console.WriteLine(dict["FieldA"]["FieldB"].Value);
NestedDictionary dict=new NestedDictionary();
dict[“一”].Value=“嵌套级别1”;
dict[“一”][“二”][“三”].Value=“嵌套级别3”;
dict[“FieldA”][“FieldB”].Value=“Hello World”;
控制台写入线(dict[“一”]值);
Console.WriteLine(dict[“一”][“二”][“三”]值);
Console.WriteLine(dict[“FieldA”][“FieldB”].Value);

为使用vb6而创建的原始
Dictionary
COM对象将通过创建具有相应名称的
Dictionary
类型的新项来响应访问不存在项的尝试。这种方法允许将某些内容存储到
MyDict[“Foo”][“Bar”]
无需首先创建
MyDict[“Foo”]
。这种方法的问题是,当执行对
MyDict[“Foo”][“Bar]”的写入操作时,人们可能希望将
“Foo”
添加到
MyDict
,但如果试图评估
MyDict[“Foo”][“Bar”],则不希望创建这样的项目.valuerDefault(someDefaultValue)

我使用过这样的集合,因为它们可以方便地建模某些东西(从概念上讲,它们非常类似于XML文档)。一种可行的方法是声明只包含其他词典的词典在语义上被视为非实体,可以随时删除。隐式添加子集合时,在添加子集合的项中设置一个标志,指示应检查是否有可能删除的项(或保留一个计数器,记录可能存在的此类项目的数量)。然后以合理的频率扫描字典,删除此类“死”项目

另一种方法是让字典中的索引器不返回实际项目,而是返回“临时索引器”类型,它保留对父对象的引用,并具有内部方法
GetNestedForReading
SetNestedForReading
GetValue
,和
SetValue
,这些方法都链接回父对象。然后一条语句
Foo[“Bar”][“Boz”]=“George”
将有效地执行
Foo.SetNestedForReading(“Bar”).SetValue(“Boz”、“George”);
z=Foo[“Bar”][“Boz”];
将有效执行public class NestedDictionary<K, V> : Dictionary<K, NestedDictionary<K, V>> { public V Value { set; get; } public new NestedDictionary<K, V> this[K key] { set { base[key] = value; } get { if (!base.Keys.Contains<K>(key)) { base[key] = new NestedDictionary<K, V>(); } return base[key]; } } }
NestedDictionary<string, string> dict = new NestedDictionary<string, string>();
dict["one"].Value = "Nest level 1";
dict["one"]["two"]["three"].Value = "Nest level 3";
dict["FieldA"]["FieldB"].Value = "Hello World";

Console.WriteLine(dict["one"].Value);
Console.WriteLine(dict["one"]["two"]["three"].Value);
Console.WriteLine(dict["FieldA"]["FieldB"].Value);