2010-07-24 62 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);