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

C#反射按名称获取字段或属性,c#,.net,reflection,null-coalescing-operator,C#,.net,Reflection,Null Coalescing Operator,有没有一种方法可以为一个函数提供一个名称,然后返回具有该名称的给定对象上的字段或属性的值?我尝试使用null coalesce操作符来解决这个问题,但显然这不喜欢不同的类型(这对我来说也有点奇怪,因为null是null)。我可以将它分离为if null,但必须有更好的方法来做到这一点。这是我的函数,两行带有比较对象的代码不会编译,但我将把它们留在那里,以显示我正在尝试做什么 private void SortByMemberName<T>(List<T> list, st

有没有一种方法可以为一个函数提供一个名称,然后返回具有该名称的给定对象上的字段或属性的值?我尝试使用null coalesce操作符来解决这个问题,但显然这不喜欢不同的类型(这对我来说也有点奇怪,因为null是null)。我可以将它分离为if null,但必须有更好的方法来做到这一点。这是我的函数,两行带有
比较
对象的代码不会编译,但我将把它们留在那里,以显示我正在尝试做什么

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);
}
private void SortByMemberName(列表、字符串memberName、bool升序)
{
类型=类型(T);
MemberInfo=type.GetField(memberName)??type.GetProperty(memberName);
if(info==null)
{
抛出新异常(“提供的成员名称既不是字段,也不是类型为“+type.FullName”的属性);
}
比较asc=(t1,t2)=>((IComparable)info.GetValue(t1)).CompareTo(info.GetValue(t2));
比较描述=(t1,t2)=>((IComparable)info.GetValue(t2)).CompareTo(info.GetValue(t1));
列表.排序(升序?asc:desc);
}
我听说有一种叫做动态LINQ的东西可以使用,但为了学习,我正在按自己的方式使用。

更改这一行:

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

MemberInfo info = type.GetField(memberName) as MemberInfo ??
    type.GetProperty(memberName) as MemberInfo;
因为这样使用三元运算符时,基类没有隐式转换。三值输出要求所有输出的类型都相同。

从开始,这将最终成为可能:

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

Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type
这意味着问题中的代码块也将编译无误;它将“看到”
FieldInfo
PropertyInfo
有一个共享的基类型,
MemberInfo

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

空合并运算符不起作用,因为
FieldInfo
不是
PropertyInfo
。使用
as
来转换它们。这不是三元运算符,而是空合并运算符。此外。。。该名称是有条件的operator@MichaelPerrenoud这可能是真的,但它们在语言规范中是独立的运算符。减法运算符可能是否定和加法的语法糖,但如果是,您会称之为加法运算符吗?(规范确实提到“三元运算符”作为条件运算符的替代名称。)@MichaelPerrenoud
?:
不遵守相同的规则。内部
void Main()
Main??默认(操作)
是编译时错误,但
为真?Main:default(Action)
完全有效。更简单,
1??2
无效,但
为真?1:2
有效。而且
正确吗?新int?(1):2
具有类型
int?
,但
新int?(1)??2
has type
int
@mattwaughan,我提供的修改后的代码行对您无效吗?