2 回答
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# 严格类型系统的阻碍:没有令人满意的方法来通用地告诉要对哪个属性进行切片。
可能的解决方案:
将getter和setter作为 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
会更好。
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);
}
}
- 2 回答
- 0 关注
- 120 浏览
添加回答
举报