扩展方法中获取类型成员的简单语法(C#)

3

我正在尝试编写一个扩展方法,使用lambda表达式来获取给定类型的成员的MemberInfo。理想情况下,我希望能够编写如下代码:

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#可以推断它们。据我所见,如果我只是找到正确的方法来指定扩展方法签名,应该有足够的信息(至少是最后一个)在代码片段中推断出所有内容,但根据编译器的说法,这并不是这样的。
我已经阅读了一篇关于静态扩展方法的旧博客文章,但我没有找到任何比那更近的东西。如果这成真了,我就能写:
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个回答

2
这个怎么样:
public static MemberInfo GetMember<TType, TReturnType>
    (this TType ignored,
     Expression<Func<TType, TReturnType>> expression)

然后您可以这样调用:

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

虽然有点棘手,但使用default(MyType)是获取类型为MyType的表达式的简单高效方式,这正是您需要进行类型推断的内容。


使用default(MyType)实际上并不比使用typeof(MyType)更棘手,所以这绝对是一个好的解决方案。您知道静态扩展方法是否被考虑用于未来的框架版本吗? - Tomas Aschan
但是,我又卡住了: 当我有这个表达式时,我该如何获得实际的“MemberInfo”呢?我试图提取我放入的成员的名称(从m.MyProperty"MyProperty")来使用内置的GetMember方法并获取成员,但我找不到 lambda 表达式的正确属性... - Tomas Aschan
@Tomas:在表达式树中查找,你会发现一个MemberExpression,它指定了要使用哪个属性。我现在无法给你一个示例,但基本上你需要分解表达式树,直到找到你要查找的内容。 - Jon Skeet
找到了!我需要 ((MemberExpression)member.Body).Member。它的名称可以在 Name 属性中找到,但由于我已经有了 MemberInfo,所以没有必要通过内置方法进行操作。谢谢! - Tomas Aschan

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)

然后像这样使用:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接