c# - 将元素添加到字典中,其中键是值的属性

标签 c# dictionary

我正在尝试构建一个字典,其中键是值对象的属性。但是我想在字典的 add 方法中构造值对象。有没有一种方法可以不使用中间变量来做到这一点?

例如我想执行以下操作,但当然键值在需要时不可用。

Dictionary<int,SomeComplexObject> dict = new Dicionary<int,SomeComplexObject>{
   {someComplexObject.Key, new SomeComplexObject {Key = 1, Name = "FooBar"},
   {someComplexObject.Key, new SomeComplexObject {Key = 2, Name = "FizzBang"} 
};

我是否必须以这种丑陋的方式来做:

Dictionary<int,SomeComplexObject> dict = new Dicionary<int,SomeComplexObject>();
SomeComplexObject value1 = new SomeComplexObject{Key=1,Name = "FooBar"};
dict.Add(value1.Key,value1);
SomeComplexObject value2 = new SomeComplexObject{Key=2,Name = "FizzBang"};
dict.Add(value.Key,value2);

我不认为这是同一个问题 How to use an object's identity as key for Dictionary<K,V>

因为我不是专门询问字典的键,而是在方法参数列表的后面才创建对象时是否有办法访问对象属性。

最佳答案

我认为扩展方法(如评论中所提议的)并不是您真正想要的,因为它只是部分解决方案。 IE。您将不得不为每个要使用的字典值类型编写一个新的扩展方法,这否定了寻求通用解决方案的全部意义。

相反,在我看来,您可能只想子类化 Dictionary<TKey, TValue>类型以添加​​您自己的自定义行为。您可以以通用方式只执行一次此操作,以便您可以为您希望必须以这种方式使用的每种类型提供一个委托(delegate)。

看起来像这样:

class KeyExtractorDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
    private readonly Func<TValue, TKey> _extractor;

    public KeyExtractorDictionary(Func<TValue, TKey> extractor)
    {
        _extractor = extractor;
    }

    public void Add(TValue value)
    {
        Add(_extractor(value), value);
    }
}

你会像这样使用它:

class Data
{
    public int Key { get; }
    public string Name { get; }

    public Data(int key, string name)
    {
        Key = key;
        Name = name;
    }
}

class Program
{
    static void Main(string[] args)
    {
        KeyExtractorDictionary<int, Data> dictionary =
            new KeyExtractorDictionary<int, Data>(d => d.Key)
            {
                new Data(1, "FooBar"),
                new Data(2, "FizzBang")
            };
    }
}

(我使用 Data 作为值类型类型,而不是您在问题中使用的 T,以避免将类型名称与泛型类型参数混淆。)

这样一来,您只需要编写一次类,而不管您可能想为这种类型的字典使用多少种不同的类型。然后,您可以将适合字典当前值类型的键提取器委托(delegate)传递给类构造函数。

请注意,通过这种方式,您还可以利用 C# 的集合初始化程序语法。因为你的新类型有一个 Add()方法只接受每个字典条目的值,编译器会将集合初始值设定项转换为正确的调用,以将每个对象添加到字典中。

这允许一个字典,您仍然可以在其中仅通过键值检索对象(使用自定义比较器需要一个值类型的实例,该实例具有您要查找的相同键),同时仍然解决更广泛的问题添加对象时不必明确指定 key ,以及通用性和重用性。

关于c# - 将元素添加到字典中,其中键是值的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42280889/

相关文章:

c# - ObserveOn 和 SubscribeOn - 工作完成的地方

c# - 通过仅在基类中定义序列化方法来序列化具有继承性的对象?

java - 如何从 Java 中的方法返回通用 Map

c# - 带有 IEqualityComparer(TKey) 的 C# Dictionary 的 Java 模拟

c# - 如何使用静态资源画笔的颜色?

c# - C# 中的蓝牙 GUID

c# - 披萨、线程、等待、通知。这是什么意思?

cocoa-touch - 如何在iPhone的UIView上附加键值对?

python - 一次替换字符串中的所有字符

swift - Swift 中的奇怪字典