2010-07-24 51 views
3

我試圖編寫一個擴展方法,它將使用lambda表達式爲我提供表示給定類型成員的MemberInfo。理想情況下,我想能夠寫用於獲取擴展方法中的類型成員的簡單語法(C#)

var info = MyType.GetMember(m => m.MyProperty); 

,或者也可以接受

var info = typeof(MyType).GetMember(m => m.MyProperty); 

甚至

var info = typeof(MyType).GetMember((MyType m) => m.MyProperty); 

我有一個可行的泛型方法簽名,但需要我指定所有的類型參數,我非常喜歡C#來推斷它們。就我所見,如果我找到了指定擴展方法簽名的正確方法,則代碼片段中應該有足夠的信息(至少是最後一個)來推斷所有內容 - 但根據編譯器的說法, 「T。

我讀過an old blog post on static extension methods但我還沒有找到任何更新的東西。如果這成爲現實,我可以寫

public static MemberInfo GetMember<TType, TReturnType>(static TType, Expression<Func<TType, TReturnType>> member) 

這將解決我的問題。但正如我所說,我似乎堅持實例擴展,在這種情況下

public static MemberInfo GetMember<TType, TReturnType>(this Type t, Expression<Func<TType, TReturnType>> member) 

只是不夠好的編譯器推斷類型成員。

回答

2

如何:

public static MemberInfo GetMember<TType, TReturnType> 
    (this TType ignored, 
    Expression<Func<TType, TReturnType>> expression) 

,你會再打電話這樣的:

default(MyType).GetMember(m => m.MyProperty) 

這是一個有點噁心,但使用default(MyType)是獲得的表達的一種簡單而有效的方法鍵入MyType,這是你想要的類型推斷。

+0

使用'默認(的MyType)'實際上是不是真的比使用'typeof運算(的MyType)'更噁心的,所以它絕對是一個很好的解決方案。你知道靜態擴展方法是否適用於任何未來版本的框架? – 2010-07-25 11:31:03

+0

但是好的,我又被卡住了:當我有這個表達式時,我如何獲得我正在尋找的實際'MemberInfo'?我試圖提取我放入的成員的名稱(從'm.MyProperty'轉到'「MyProperty」')以使用內置的'GetMember'方法並獲取成員,但我找不到lambda表達式的正確屬性... – 2010-07-25 12:25:03

+0

@Tomas:查看錶達式樹,並且您會找到一個MemberExpression,它指定要使用哪個屬性。我現在不能給你一個樣本,但基本上你需要分解表達式樹中的內容,直到找到你要找的東西。 – 2010-07-25 13:31:03

0

如果你沒有一個實例,我覺得你可以做的最好的是:

public static MemberInfo GetMember<TType, TReturnType>(Expression<Func<TType, ReturnType>> member) 

然後,使用這樣的:

MemberInfo info = YourClass.GetMember((YourConcreteType instance) => instance.Property); 

你可以把過載,它接受一個實例作爲第一個參數,因此只要有實例,就可以使用擴展方法語法:

public static MemberInfo GetMember<TType, TReturnType>(this TType instance, Expression<Func<TType, ReturnType>> member) 

T母雞用這樣的:

MemberInfo info = yourInstanceOfTType.GetMember(instance => instance.Property);