有没有办法为函数提供一个名称,然后该函数返回具有该名称的给定对象上的字段或属性的值?我尝试使用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,但为了学习,我正在按照自己的方式进行。
答案 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
这意味着问题中的代码块也将正确编译。它会“看到” FieldInfo
和PropertyInfo
具有共享的基本类型MemberInfo
。
MemberInfo info = type.GetField(memberName) ?? type.GetProperty(memberName);