简体   繁体   English

如果键不存在,则使用setter的C#自定义词典类型

[英]C# Custom dictionary type with setter if key does not exist

I am trying to define a custom type which extends the DIctionary with only one difference. 我正在尝试定义一个自定义类型,该自定义类型仅以一个差异扩展了词典。 when I set a value like this: 当我设置这样的值时:

myCustomDic[3.5] = 4.0;

it first checks if the key 3.5 exists. 它首先检查密钥3.5是否存在。 if it does, sets the value to the new one. 如果是这样,请将值设置为新值。 otherwise it adds the key with the new value. 否则,它将使用新值添加密钥。 I did it like this: 我这样做是这样的:

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

and I use it like this: 我这样使用它:

var testDic = new Dic(new Dictionary<double, double>());
testDic[2.5] = 4.0;

However there is no key and value pair added to testDic? 但是,没有将键和值对添加到testDic吗? could somebody please tell why? 有人可以告诉为什么吗?

Because you are subclassing Dictionary , you don't need your own private Dictionary as well. 因为您是Dictionary的子类,所以您也不需要自己的私有Dictionary。 Also, the behaviour you describe is how Dictionary already works, so you don't need to create your own class at all: 另外,您描述的行为是Dictionary已如何工作,因此您根本不需要创建自己的类:

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

From the documentation at Dictionary<TKey, TValue>.Item Property (TKey) : Dictionary<TKey, TValue>.Item Property (TKey)的文档中:

When you set the property value, if the key is in the Dictionary, the value associated with that key is replaced by the assigned value. 设置属性值时,如果键在词典中,则与该键关联的值将由分配的值替换。 If the key is not in the Dictionary, the key and value are added to the dictionary. 如果键不在词典中,则将键和值添加到词典中。

But you can: 但是你可以:

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

Then you can do: 然后,您可以执行以下操作:

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

This is because you check the Count property which remains zero because you did not overwrite it. 这是因为您检查了Count属性,该属性仍为零,因为您没有覆盖它。

The count of your _property will increase but not the external one. 您的_property的数量会增加,但外部的数量不会增加。

The debugger visualizer will still call the original Dictionary count which will still report 0 but if you print it to console it will work. 调试器可视化器仍将调用原始词典计数,该计数仍将报告为0,但如果将其打印到控制台,它将起作用。

I still do not understand why you derive from the Dictionary because the way you describe your requirement is already implemented by the 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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM