2013-04-30 60 views
8

是否有办法为函数提供一个名称,然后返回给定对象上的字段或属性的值的名称?我尝试用null-coalesce运算符解决它,但显然不喜欢不同的类型(这对我来说也有点奇怪,因为null为空)。如果是空值,我可以将它分开,但必须有更好的方法来做到这一点。这是我的功能,并且与Comparison对象的两行不能编译,但我将它们留在那里以显示我正在尝试执行的操作。C#反射按名称获取字段或属性

private void SortByMemberName<T>(List<T> list, string memberName, bool ascending) 
{ 
    Type type = typeof (T); 
    MemberInfo info = type.GetField(memberName) ?? type.GetProperty(memberName); 

    if (info == null) 
    { 
     throw new Exception("Member name supplied is neither a field nor property of type " + type.FullName); 
    } 

    Comparison<T> asc = (t1, t2) => ((IComparable) info.GetValue(t1)).CompareTo(info.GetValue(t2)); 
    Comparison<T> desc = (t1, t2) => ((IComparable) info.GetValue(t2)).CompareTo(info.GetValue(t1)); 

    list.Sort(ascending ? asc : desc); 
} 

我听说过可以使用动态linq的东西,但为了学习,我按照自己的方式去做。

+2

null合并运算符不起作用,因为FieldInfo不是“PropertyInfo”。使用'as'来施放它们。 – FlyingStreudel 2013-04-30 17:21:36

回答

12

改变这一行:

MemberInfo info = type.GetField(memberName) ?? type.GetProperty(memberName); 

这样:

MemberInfo info = type.GetField(memberName) as MemberInfo ?? 
    type.GetProperty(memberName) as MemberInfo; 

因为使用三元运算符一样,当没有隐式转换为基类。三元要求所有输出的类型相同。

+4

这不是三元运算符,它是空合并运算符。 – 2013-04-30 17:29:24

+1

此外......名称是* conditional *运算符 – 2013-04-30 17:34:30

+0

@MichaelPerrenoud这可能是事实,但它们是语言规范中的独立运算符。减法运算符可能是用于否定和加法的语法糖,但是如果是这样,你会把它称为加法运算符吗? (规范确实提到“三元运算符”作为条件运算符的替代名称。) – 2013-04-30 17:51:44