如果键不存在,C# 自定义字典类型 setter
C# Custom dictionary type with setter if key does not exist
我正在尝试定义一个自定义类型,它扩展了 DIctionary,只有一个区别。当我设置这样的值时:
myCustomDic[3.5] = 4.0;
它首先检查密钥 3.5 是否存在。如果是,则将值设置为新值。否则它会添加具有新值的键。我是这样做的:
class Dic : Dictionary<double, double>
{
private readonly Dictionary<double, double> _property;
public Dic(Dictionary<double, double> property)
{
_property = property;
}
//Indexer:
public new double this[double CA]
{
get
{
return _property[CA];
}
set
{
if (_property.ContainsKey(CA))
{
_property[CA] = value;
}
else
{
_property.Add(CA, value);
}
}
}
}
我是这样使用它的:
var testDic = new Dic(new Dictionary<double, double>());
testDic[2.5] = 4.0;
但是testDic中没有添加键值对?
有人能告诉我为什么吗?
因为您正在 classing Dictionary
,所以您也不需要自己的私人词典。此外,您描述的行为是 Dictionary
已经工作的方式,因此您根本不需要创建自己的 class:
var t2 = new Dictionary<double, double>();
t2[2.5] = 4.0;
Console.WriteLine(t2[2.5]); // outputs 4
t2[2.5] = 8.0;
Console.WriteLine(t2[2.5]); // outputs 8
来自 Dictionary<TKey, TValue>.Item Property (TKey)
的文档:
当您设置 属性 值时,如果该键在字典中,则与该键关联的值将替换为分配的值。如果键不在字典中,则将键和值添加到字典中。
但是你可以:
class Dic : Dictionary<double, double> {
//Indexer:
public new double this[double CA] {
get => (this as Dictionary<double, double>)[CA];
set {
var parent = this as Dictionary<double, double>;
if (parent.ContainsKey(CA))
parent[CA] = value;
else
parent.Add(CA, value);
}
}
}
那么你可以这样做:
var testDic = new Dic();
testDic[2.5] = 4.0;
Console.WriteLine(testDic[2.5]); // this outputs 4
testDic[2.5] = 8.0;
Console.WriteLine(testDic[2.5]); // this outputs 8
这是因为您检查了计数 属性,它仍然为零,因为您没有覆盖它。
你的 _属性 的计数会增加,但外部的不会。
调试器可视化工具仍会调用原始字典计数,它仍会报告 0,但如果您将其打印到控制台,它会起作用。
我还是不明白你为什么要从Dictionary派生,因为你描述需求的方式已经被Dictionary实现了。
public TValue this[TKey key]
{
get
{
int num = this.FindEntry(key);
if (num >= 0)
{
return this.entries[num].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
set
{
this.Insert(key, value, false);
}
}
我正在尝试定义一个自定义类型,它扩展了 DIctionary,只有一个区别。当我设置这样的值时:
myCustomDic[3.5] = 4.0;
它首先检查密钥 3.5 是否存在。如果是,则将值设置为新值。否则它会添加具有新值的键。我是这样做的:
class Dic : Dictionary<double, double>
{
private readonly Dictionary<double, double> _property;
public Dic(Dictionary<double, double> property)
{
_property = property;
}
//Indexer:
public new double this[double CA]
{
get
{
return _property[CA];
}
set
{
if (_property.ContainsKey(CA))
{
_property[CA] = value;
}
else
{
_property.Add(CA, value);
}
}
}
}
我是这样使用它的:
var testDic = new Dic(new Dictionary<double, double>());
testDic[2.5] = 4.0;
但是testDic中没有添加键值对? 有人能告诉我为什么吗?
因为您正在 classing Dictionary
,所以您也不需要自己的私人词典。此外,您描述的行为是 Dictionary
已经工作的方式,因此您根本不需要创建自己的 class:
var t2 = new Dictionary<double, double>();
t2[2.5] = 4.0;
Console.WriteLine(t2[2.5]); // outputs 4
t2[2.5] = 8.0;
Console.WriteLine(t2[2.5]); // outputs 8
来自 Dictionary<TKey, TValue>.Item Property (TKey)
的文档:
当您设置 属性 值时,如果该键在字典中,则与该键关联的值将替换为分配的值。如果键不在字典中,则将键和值添加到字典中。
但是你可以:
class Dic : Dictionary<double, double> {
//Indexer:
public new double this[double CA] {
get => (this as Dictionary<double, double>)[CA];
set {
var parent = this as Dictionary<double, double>;
if (parent.ContainsKey(CA))
parent[CA] = value;
else
parent.Add(CA, value);
}
}
}
那么你可以这样做:
var testDic = new Dic();
testDic[2.5] = 4.0;
Console.WriteLine(testDic[2.5]); // this outputs 4
testDic[2.5] = 8.0;
Console.WriteLine(testDic[2.5]); // this outputs 8
这是因为您检查了计数 属性,它仍然为零,因为您没有覆盖它。
你的 _属性 的计数会增加,但外部的不会。
调试器可视化工具仍会调用原始字典计数,它仍会报告 0,但如果您将其打印到控制台,它会起作用。
我还是不明白你为什么要从Dictionary派生,因为你描述需求的方式已经被Dictionary实现了。
public TValue this[TKey key]
{
get
{
int num = this.FindEntry(key);
if (num >= 0)
{
return this.entries[num].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
set
{
this.Insert(key, value, false);
}
}