簡體   English   中英

物業KeyValuePair <TKey, Tvalue> .Value沒有二傳手

[英]The property KeyValuePair<TKey, Tvalue>.Value has no setter

我正在使用Dictionary<int, KeyValuePair<bool, int>>來保存數據。

我不時需要在KeyValuePair增加int ,但它不會讓我,因為它沒有setter。 有沒有辦法增加它?

代碼示例:

Dictionary<int, KeyValuePair<bool, int>> mDictionary = 
    new Dictionary<int, KeyValuePair<bool, int>>();

mDictionary[trapType].Value++;
//Error: The property KeyValuePair<TKey, Tvalue>>.Value has no setter

有沒有辦法增加它?

KeyValuePair是不可變的 - 它也是一個值類型,因此在創建副本后更改Value屬性的Value無論如何都無濟於事。

你必須寫這樣的東西:

var existingValue = mDictionary[trapType];
var newValue = new KeyValuePair<bool, int>(existingValue.Key,
                                           existingValue.Value + 1);
mDictionary[trapType] = newValue;

這很丑陋 - 你真的需要價值成為KeyValuePair嗎?

mDictionary[trapType] = new KeyValuePair<bool, int>(mDictionary[trapType].Key, mDictionary[trapType].Value+1)

KeyValuePair往往只是用作字典的迭代器值。 如果你希望它是可變的,你最好定義自己的類型。

您需要構造一個新的鍵值對。

mDictionary[trapType] = new KeyValuePair<bool,int>(mDictionary[trapType].Key,mDictionary[trapType].Value +1);

但是,如果您使用的是.NET 4,我建議您使用Tuple而不是鍵值對,如果您要做的只是擁有一個包含兩個其他值的對象。 即如果兩者之間沒有鍵值關系。 然后代碼將是:

mDictionary[trapType] = Tuple.Create(mDictionary[trapType].Item1,mDictionary[trapType].Item2 +1);

另一個解決方案是創建一個新的字典並將新的值和鍵傳遞給它:

foreach (var d in existingDic)
                    newDic.Add(d.Key, d.Value + 1);

從概念上講, KeyValuePair<TKey,TValue>只是一對變量, KeyValue 如果微軟用暴露的公共字段KeyValue實現它,它的語義就會很完美; 當用作ForEach控制變量時,它本來是不可變的,但是可以更新普通變量或數組元素的Key或Value字段,而不必更新另一個。

遺憾的是,微軟似乎一直不願意讓框架類型暴露任何公共字段,即使是像KeyValuePair<TKey,TValue>Drawing.Rectangle這樣的類型,其語義規定(1)類型必須是結構; (2)其整個狀態在一組固定的屬性中可見(除了定義對象狀態的屬性之外,可能還有其他計算屬性),以及(3)可以為這些屬性分配適合其類型的任何值組合。 因此,Microsoft僅考慮了將包含類型狀態的成員公開為只讀屬性或讀寫屬性的可能性。 使用讀寫屬性意味着代碼如下:

for each (var item in myDictionary)
    item.Value += 1;

要么

...assuming MyList is a List<Drawing.Rectangle>
MyList[3].Width += 9;

將被現有的C#編譯器解釋為

for each (var item in myDictionary)
{ var temp = item; temp .Value += 1; }

要么

...assuming MyList is a List<Drawing.Rectangle>
{ temp = MyList[3]; temp.Width += 9; }

產生可怕的行為幾乎肯定不是程序員的意圖。 .net的實施者認為讓KeyValuePair<TKey,TValue>的成員具有個體可變性的價值並不能證明前者所構成的危險,但修改Rectangle個體成員的有用性足以證明由此造成的危險。第二。 請注意,如果類型使用公開的字段而不是屬性,則兩個示例都不必構成任何危險,因為即使在調用屬性setter時,也不允許寫入臨時結構的字段。

如前所述,KeyValuePair是不可變的。 我認為值得在這里添加一個可變的實現:

public class MutableKeyValuePair<KeyType, ValueType>
    {
        public KeyType Key { get; set; }
        public ValueType Value { get; set; }

        public MutableKeyValuePair() { }

        public MutableKeyValuePair(KeyType key, ValueType val)
        {
            Key = key;
            Value = val;
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM