【问题标题】:C# Reflection get Field or Property by NameC# 反射按名称获取字段或属性
【发布时间】:2013-04-24 16:56:46
【问题描述】:

有没有办法为函数提供名称,然后返回具有该名称的给定对象的字段或属性的值?我尝试使用 null-coalesce 运算符来解决它,但显然它不喜欢不同的类型(这对我来说也有点奇怪,因为 null 是 null)。我可以将它分成 if nulls,但必须有更好的方法来做到这一点。这是我的函数,带有 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 的东西,但是为了学习,我按照自己的方式来做。

【问题讨论】:

  • 空合并运算符不起作用,因为 FieldInfo 不是 PropertyInfo。使用as 投射它们。

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


【解决方案1】:

截至C# 9.0,这终于成为可能:

目标类型 ??和?:

有时是有条件的??和 ?: 表达式在分支之间没有明显的共享类型。这种情况今天失败了,但如果有两个分支都转换为的目标类型,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);

【讨论】:

    【解决方案2】:

    改变这一行:

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

    到这里:

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

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

    【讨论】:

    • 这不是三元运算符,而是空合并运算符。
    • 另外...名字是条件操作符
    • @MichaelPerrenoud 这可能是真的,但它们在语言规范中是独立的运算符。减法运算符可能是否定和加法的语法糖,但如果是这样,你会称它为加法运算符吗? (并且规范确实提到了“三元运算符”作为条件运算符的替代名称。)
    • @MichaelPerrenoud ?: 和 ?? 不遵守相同的规则。在void Main()、Main ?? default(Action) 内部是编译时错误,但true ? Main : default(Action) 完全有效。更简单的是,1 ?? 2 无效,但 true ? 1 : 2 有效。而true ? new int?(1) : 2 的类型为int?,但new int?(1) ?? 2 的类型为int。
    • @MattVaughan,我提供的修改后的代码行对你不起作用吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    相关资源
    最近更新 更多