用于“获取”任何对象属性的通用方法

时间:2011-03-03 02:44:21

标签: c# generics dictionary properties

假设我有一个Dictionary对象,其中包含一个名为SomeObject的对象的许多实例,每个SomeObject都有一个名为Property1和Property2的属性。现在说我有一个方法可以返回一个按Property1排序的新Dictionary。但是,我想概括一下这个方法,以便我可以告诉它要对哪个属性进行排序。

例如,要做到这一点,我知道我可以轻松地使用两种不同的方法,例如:

public Dictionary<string, SomeObject> SortByProp1(Dictionary<string, SomeObject> dict) { ... }
public Dictionary<string, SomeObject> SortByProp2(Dictionary<string, SomeObject> dict) { ... }

但是,我想知道是否可以将这些组合成一种方法,我可以在其中给出一个参数来识别要返回的方法?我不知道如何概括这样的财产......

注意:我意识到我总是可以使用类似if语句的东西,它可以基于属性名称的字符串,但这似乎不是一个非常优雅,可接受的答案比开始使用两种不同的方法要好得多。

3 个答案:

答案 0 :(得分:4)

您寻找的方法内置于IEnumerable<T>界面,并且是OrderBy,尽管它可能不像您想要的那样对字典有效。

Dictionary<TKey, TValue>实现IEnumerable<KeyValuePair<TKey, TValue>>,因此它的OrderBy方法接受一个lambda表达式,该表达式本身采用KeyValuePair<TKey, TValue>,并返回一个描述您要排序的选择器方法。

例如,如果您有Dictionary<int, Customer>,则会返回按客户名称排序的IEnumerable<KeyValuePair<int, Customer>>

myDict.OrderBy(kvp => kvp.Value.Name);

然后,按照这个排序顺序获得客户自己,你会说:

IEnumerable<Customer> orderedByName = myDict.OrderBy(kvp => kvp.Value.Name).Select(kvp => kvp.Value);

答案 1 :(得分:2)

您可以尝试为订购密钥添加泛型类型参数 - 并接受订购的谓词吗?

如:

public Dictionary<string, SomeObject> SortByProp<TProp>(Dictionary<string, SomeObject> dict, Expression<SomeObject,TProp> orderPredicate) 
{
   return dict.OrderBy(orderPredicate);
}

// Usage: 
SortByProp(apples, x => x.AppleColor);
SortByProp(oranges, x => x.OrangeType);

答案 2 :(得分:2)

您可以接受委托选择属性:

public Dictionary<string, SomeObject> Sort<TProperty>(Dictionary<string, SomeObject> dict, Func<SomeObject, TProperty> selector) { ... }

您可以这样称呼它:

var sortedDict = Sort(dict, o => o.Property1);