简体   繁体   English

使用自定义对象作为字典键,但按对象属性获取值

[英]Using custom object as dictionary key but get values by object property

I have a class: 我有一节课:

public class Foo
{
    public string Name { get; set; }
    public double Value { get; set; }

    public override string ToString()
    {
        return Name;
    }
}

And I need to create a dictionary where key is object of Foo. 我需要创建一个字典,其中key是Foo的对象。 Like this: 像这样:

Foo foo1 = new Foo { Name = "Foo1", Value = 2.2 };
Foo foo2 = new Foo { Name = "Foo2", Value = 3.6 };

Dictionary<Foo, int> dic = new Dictionary<Foo, int>();
dic.Add(foo1, 1234);
dic.Add(foo2, 2345);

And now I want to get values from dictionary by passing Foo.Name property as key. 现在我想通过传递Foo.Name属性作为键从字典中获取值。 Like this: 像这样:

int i=dic["Foo1"];
// i==1234
i = dic["Foo2"];
// i==2345

Is it possible? 可能吗? Or the only way to pass object of Foo as key and override Equals method? 或者将Foo的对象作为键传递并覆盖Equals方法的唯一方法?

If you use a Foo as a key, you will need to use a Foo to index the dictionary as well. 如果使用Foo作为键,则还需要使用Foo来索引字典。

Provided that what you actually need is most likely a Dictionary<string, int> , you could try overriding GetHashCode and Equals so that you can compare Foo objects based on the name only: 如果您实际需要的很可能是Dictionary<string, int> ,您可以尝试重写GetHashCodeEquals以便您可以仅根据名称比较Foo对象:

using System.Collections.Generic;

public class Foo {
    public string Name { get; set; }
    public double Value { get; set; }

    public override string ToString() {
        return Name;
    }
    public override int GetHashCode() {
        return Name.GetHashCode();
    }
    public override bool Equals(object obj) {
        Foo other = obj as Foo;
        if (other == null) {
            return false;
        }
        return Name.Equals(other.Name);
    }
}

class Program {
    static void Main(string[] args) {

        Foo foo1 = new Foo { Name = "Foo1", Value = 2.2 };
        Foo foo2 = new Foo { Name = "Foo2", Value = 3.6 };

        Dictionary<Foo, int> dic = new Dictionary<Foo, int>();
        dic.Add(foo1, 1234);
        dic.Add(foo2, 2345);

        int i = dic[new Foo { Name = "Foo1" }];

    }
}

How about this: 这个怎么样:

class Program
{
    public class Foo
    {
        public string Name { get; set; }
        public double Value { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }

    static void Main(string[] args)
    {
        Foo foo1 = new Foo { Name = "Foo1", Value = 2.2 };
        Foo foo2 = new Foo { Name = "Foo2", Value = 3.6 };

        var dic = new Dictionary<string, KeyValuePair<Foo, int>>();
        dic.Add(foo1.Name, new KeyValuePair<Foo, int>(foo1, 1234));
        dic.Add(foo2.Name, new KeyValuePair<Foo, int>(foo2, 2345));

        int x = dic["Foo1"].Value;

        var y = dic["Foo2"].Value;

        Console.WriteLine(x);
        Console.WriteLine(y);

        Console.ReadKey();
    }
}

Result will be: 结果将是:

1234 1234

2345 2345

The Dictionary is based on a hash table, that means it uses a hash lookup, which is a rather efficient algorithm to look up things. Dictionary基于哈希表,这意味着它使用哈希查找,这是一种查找事物的相当有效的算法。 I suggest you think on your design and just use Dictionary<string,int> if you just want to use string as key 我建议你考虑你的设计,如果你只想使用string作为key ,只需使用Dictionary<string,int>

As a work around( not preferred way use only if you can't change your design), you could do this. 作为一种解决方法(只有当你不能改变你的设计时才使用这种方法),你可以做到这一点。

var key = dic.Keys.FirstOrDefault(c=>c.Name == "Foo1");     

if(key != null)
    dic[key]; //

Ok. 好。 I solved it by creating a class inherits Dictionary and overriding get value method. 我通过创建一个继承Dictionary和重写get value方法来解决它。 This solves my problem but I'm not sure about productivity with large collections. 这解决了我的问题,但我不确定大型集合的生产力。

public class MyDictionary:Dictionary<Foo, int>
{
    public Bar():base()
    {

    }

    new public int this[string key]
    {
        get
        {
            return this[base.Keys.Single(a => a.Name == key)];
        }
    }
}

And then this code works well: 然后这段代码效果很好:

    MyDictionary<Foo, int> dic = new MyDictionary<Foo, int>();
    dic.Add(foo1, 1234);
    dic.Add(foo2, 2345);
    int i=dic["Foo1"];

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

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