2013-04-30 85 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