亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 C# 中對字典進行切片

在 C# 中對字典進行切片

C#
蕭十郎 2023-09-16 16:17:00
bigDict我正在嘗試在 C# 中創建一個類,該類具有從 JSON 文件獲取的字典 ( )。bigDict將字符串映射到大數據結構。由此,我想創建另一個字典 ( ),將鍵中的每個字符串映射到的數據結構值smallDict中的一個元素(字符串) 。bigDict我嘗試使用 get 和 set 來創建smallDict. 我能夠成功使用get,但我陷入了困境set。class myClass{    public Dictionary<string, SomeStruct> bigDict{ get; set; } /*get and set from a JSON file*/    public virtual Dictionary<string, string> smallDict    {        get => bigDict.ToDictionary(x => x.Key, x => x.Value.ElemFromStruct);   //works fine        set => smallDict.ToDictionary.update(key , value); //doesn't work fine    }}由于無法正確設置,我property or indexer cannot be assigned to, is readonly在一些預先存在的測試用例中遇到錯誤(我正在重構代碼)
查看完整描述

2 回答

?
慕的地8271018

TA貢獻1796條經驗 獲得超4個贊

定義“一次性”類型SmallDict:


? ? public SmallDict<string> smallDict;


? ? public myClass()

? ? {

? ? ? ? smallDict = new SmallDict<string>(bigDict);

? ? }

? ? class SmallDict<TKey>

? ? {

? ? ? ? public readonly Dictionary<TKey, SomeStruct> BigDict;


? ? ? ? public SmallDict(Dictionary<TKey, SomeStruct> bigDict)

? ? ? ? {

? ? ? ? ? ? BigDict = bigDict;

? ? ? ? }


? ? ? ? public string this[TKey key]

? ? ? ? {

? ? ? ? ? ? get => BigDict[key].ElemFromStruct;

? ? ? ? ? ? set {

? ? ? ? ? ? ? ? var obj = BigDict[key];

? ? ? ? ? ? ? ? obj.ElemFromStruct = value;

? ? ? ? ? ? ? ? BigDict[key] = obj;

? ? ? ? ? ? }

? ? ? ? }

? ? }

使用方法如下:


Console.WriteLine(smallDict["key1"]); // Equivalent to printing bigDict[key].ElemFromStruct

smallDict["key1"] = "new value";? ? ? // Equivalent to bigDict[key].ElemFromStruct = "new value"

它只是字典的包裝,因此如果您想要比普通索引更多的方法,則必須手動完成所有管道操作。

通用性

請注意如何SmallDict僅適用于SomeStruct...的詞典

我本想編寫一個通用的DictionarySlice類,但任何實際通用性的嘗試都會受到 C# 嚴格類型系統的阻礙:沒有令人滿意的方法來通用地告訴要對哪個屬性進行切片。

可能的解決方案:

  • gettersetter作為 lambda 傳遞——當然您可以這樣做,請注意,您的 lambda 中的代碼將比實際類中的代碼多。如果您需要對許多不同的屬性進行切片,它可能會很有用。

  • 制作泛型類將使用的SomeStruct實現——不是非常優雅,而且如果您有許多屬性需要切片,則可能非常麻煩。IGetSetElemFromStruct

  • 反射——包含在內是為了完整性,但不會對其進行擴展......

大型結構

避免大型結構;更重要的是,避免可變結構,這在 C# 中被普遍認為是非常糟糕的事情(TM) 。根據微軟的設計指南,我的重點是:

一般來說,結構體非常有用,但只能用于不會經常裝箱的小型、單一、不可變的值。

set?{????var?obj?=?BigDict[key];
????obj.ElemFromStruct?=?value;
????BigDict[key]?=?obj;
}

請注意,在上面的 setter 中,我獲取了結構的副本,修改它,然后將其復制回字典......不太好。如果它很大,請幫自己一個忙并使用class.?然后你可以簡單地寫:

set?{?BigDict[key].ElemFromStruct?=?value;?}

屬性獲取/設置中的重要操作

這是關于您作為示例編寫的代碼:

public?virtual?Dictionary<string,?string>?smallDict
{????get?=>?bigDict.ToDictionary(x?=>?x.Key,?x?=>?x.Value.ElemFromStruct);???//works?fine

盡可能避開它們。沒有明確的界限說明屬性 getters/setters 中可以包含什么內容,但是get以任何合理的標準來看,在 a 中創建和填充字典都太過分了:想象一下,如果您不得不懷疑每個屬性訪問。

也許根本不使用這個

這個解決方案是我能想到的最好的解決方案,但它很笨重而且不是很有用。您必須根據您的用例自行判斷,但通常直接訪問/修改bigDict[key].ElemFromStruct會更好。


查看完整回答
反對 回復 2023-09-16
?
拉風的咖菲貓

TA貢獻1995條經驗 獲得超2個贊

如果我理解正確的話,您希望能夠Dictionary<string, SomeStruct>從Dictionary<string, string>. 為此,您需要從字符串 Value 創建該結構的實例。這是可以完成的,但這意味著該SomeStruct值ElemFromStruct在set.


請注意,對于任何屬性,在set方法內部,都有一個value與屬性(在本例中)類型相同的可用變量Dictionary<string, string>,它表示傳遞到方法中的項set。這在下面用作value.ToDictionary(...


例如:


public virtual Dictionary<string, string> SmallDict

{

    get

    {

        return BigDict.ToDictionary(x => x.Key, x => x.Value.ElemFromStruct);

    }

    set

    {

        BigDict = value.ToDictionary(x => x.Key,

            x => new SomeStruct {ElemFromStruct = x.Value});

    }

}

但是,如果目的只是提供一種SmallDict從 a獲取 a 的方法BigDict(而不是相反),那么您可以刪除該set方法,因為允許用戶BigDict僅基于a 進行設置可能沒有多大意義每個值對應一個字符串SomeStruct:


public virtual Dictionary<string, string> SmallDict

{

    get

    {

        return BigDict.ToDictionary(x => x.Key, x => x.Value.ElemFromStruct);

    }

}


查看完整回答
反對 回復 2023-09-16
  • 2 回答
  • 0 關注
  • 163 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號