2012-02-15 78 views
2

我正在为我的任务写一个自定义字典类,但它给错误。这个班有什么问题?谢谢为什么这个自定义字典类不工作 - C#4.0

 public struct MyValue 
    { 
     public int irValue1; 
     public int irValue2; 
    } 

    public class csCustomDictionary : Dictionary<string, MyValue> 
    { 
     public void Add(string srKey, int irVal1, int irVal2) 
     { 
      if (this.ContainsKey(srKey) == true) 
      { 
       this[srKey].irValue1 = this[srKey].irValue1 + irVal1; 
       this[srKey].irValue1 = this[srKey].irValue2 + irVal2; 
      } 
      else 
      { 
       MyValue val; 
       val.irValue1 = irVal1; 
       val.irValue2 = irVal2; 
       this.Add(srKey, val); 
      } 
     } 
    } 
} 

这是错误消息

enter image description here

C#4.0

这是修改后的版本正确

public class csMyValue 
{ 
    public int irValue1; 
    public int irValue2; 
} 

public class csCustomDictionary : Dictionary<string, csMyValue> 
{ 
    public void Add(string srKey, int irVal1, int irVal2) 
    { 
     if (this.ContainsKey(srKey) == true) 
     { 
      this[srKey].irValue1 = this[srKey].irValue1 + irVal1; 
      this[srKey].irValue1 = this[srKey].irValue2 + irVal2; 
     } 
     else 
     { 
      csMyValue val = new csMyValue(); 
      val.irValue1 = irVal1; 
      val.irValue2 = irVal2; 
      this.Add(srKey, val); 
     } 
    } 
} 
+1

* *什么错误?它在哪里?你有例外吗?它没有按预期执行吗?不要让我们成为侦探。 – 2012-02-15 00:50:31

+0

添加了错误图像。请刷新并重新检查 – MonsterMMORPG 2012-02-15 00:53:56

+2

您是否知道只需单击该错误并按F1即可获取此帮助页面? [编译器错误CS1612](http://msdn.microsoft.com/en-us/library/wydkhw2c(v = vs.100).aspx) – 2012-02-15 00:59:35

回答

3

问题是你在字典中使用了struct作为你的值。

当您编写:this[srKey]时,您实际上会检索存储为字典值的结构的副本。因此,.irValue1正试图在副本上设置一个字段(即将消失)。

如果您将MyValue更改为类,则应该可以工作。这也更合适,因为你正在制作一个可变类型,而可变结构很少是一个好主意。

话虽这么说,你可能会迫使该通过制作一个临时的工作,设置领域,然后在你的字典设定值:

if (this.ContainsKey(srKey) == true) 
{ 
    MyValue tmp = this[srKey]; 
    tmp.irValue1 += irVal1; 
    tmp.irValue2 += irVal2; 
    this[srKey] = tmp; 
} 

如果更改MyValue是一类的,而不是一个结构,你可以写:

MyValue tmp = this[srKey]; 
    tmp.irValue1 += irVal1; 
    tmp.irValue2 += irVal2; 

由于存储的值将是一个参考,这是不行的,你想,而不需要大量的字典查找的变化。

+0

非常感谢您的回答。我修改了问题并添加了类版本。这会工作好吗?还是有更好的方法? – MonsterMMORPG 2012-02-15 01:04:47

+1

@MonsterMMORPG类的版本将工作 - 但读了我的最后一节;)它显示了一个更好的版本使用类(获得一个tmp,增量),因为它不必做字典查找4次,只是一次。 – 2012-02-15 01:11:27

+0

因此,而不是如果我会只使用你的版本的权利?或者只是更换内部如果检查? – MonsterMMORPG 2012-02-15 01:16:42

1

我想这是说this[whatever]不能在任务的左侧。试试这个:

public class csCustomDictionary : Dictionary<string, MyValue> 
{ 
    public void Add(string srKey, int irVal1, int irVal2) 
    { 
     if (this.ContainsKey(srKey) == true) 
     { 
      var myVal = this[srKey]; 
      myVal.irValue1 = myVal.irValue1 + irVal1; 
      myVal.irValue1 = myVal.irValue2 + irVal2; 
     } 
     else 
     { 
      MyValue val; 
      val.irValue1 = irVal1; 
      val.irValue2 = irVal2; 
      this.Add(srKey, val); 
     } 
    } 
} 
+1

这将编译,但实际上并没有更改字典中的值...你的改变使得这是一个无操作。 – 2012-02-15 00:59:06

+0

但它也揭示*为什么* C#不会让你这样做:) – porges 2012-02-15 01:00:04

+0

里德,这绝对不是真的。内存中只有一个对象的副本。 – Diego 2012-02-15 02:00:17

1

C#不会让你这样做,因为MyValue是一个结构体。

this[...]方法将返回数据的副本,所以如果您更改该字段,它将不会执行任何操作。

改为改为类。

如果你真的需要它是一个结构,你可以这样做:

var tmp = this[srKey]; 
tmp.irValue1 += irVal1; 
this[srKey] = tmp; 
+0

非常感谢您的回答。我修改了问题并添加了类版本。这会工作好吗?还是有更好的方法? – MonsterMMORPG 2012-02-15 01:05:05

1

当使用索引你实际上是让你MyValue的副本,因为它是一个结构类型。编译器实际上帮助你,让你知道代码没有达到你的期望。要解决此问题,您需要直接指定一个新值。

var current = this[srKey]; 
this[srKey] = new MyValue { 
    irValue1 = current.irValue1 + irVal1, 
    irValue2 = current.irValue2 + irVal2 
}; 
0

要创建自定义词典,你需要从IDictionary <int, MyValue>继承和实现接口,添加(),删除()等