C#反射按名称获取字段或属性

时间:2013-04-30 17:18:55

标签: c# .net reflection null-coalescing-operator

有没有办法为函数提供一个名称,然后该函数返回具有该名称的给定对象上的字段或属性的值?我尝试使用null-coalesce运算符解决它,但显然不喜欢不同的类型(这对我来说也有点奇怪,因为null为null)。我可以把它分成如果为空,但必须有一个更好的方法来做到这一点。这是我的函数,带有Comparison对象的两行不能编译,但我会将它们留在那里以显示我想要做的事情。

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 个答案:

答案 0 :(得分:15)

更改此行:

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

到此:

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

因为在使用这样的三元运算符时没有对基类的隐式强制转换。三元组要求所有输出的类型相同。

答案 1 :(得分:1)

C# 9.0开始,这将最终成为可能:

键入的目标?和?:

有时是有条件的?和?:表达式在分支之间没有明显的共享类型。这样的情况今天失败了,但是如果两个分支都将目标类型都转换为:C#9.0将允许它们。

Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type

这意味着问题中的代码块也将正确编译。它会“看到” FieldInfoPropertyInfo具有共享的基本类型MemberInfo

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