C# 标识MethodInfo实例是否为属性访问器

C# 标识MethodInfo实例是否为属性访问器,c#,reflection,C#,Reflection,我正在使用编写一个装饰代理。我需要代理的拦截器仅拦截属性写入(而不是读取),因此我正在检查方法的名称,因此: public void Intercept(IInvocation invocation) { if (invocation.Method.Name.StartsWith("set_") { // ... } invocation.Proceed(); } 现在这很好,但我不喜欢我的代理对属性的实现方式有深入的了解:我想用类似于以下内容

我正在使用编写一个装饰代理。我需要代理的拦截器仅拦截属性写入(而不是读取),因此我正在检查方法的名称,因此:

public void Intercept(IInvocation invocation)
{
    if (invocation.Method.Name.StartsWith("set_")
    {
        // ...
    }

    invocation.Proceed();
}
现在这很好,但我不喜欢我的代理对属性的实现方式有深入的了解:我想用类似于以下内容的内容替换方法名称检查:

if (invocation.Method.IsPropertySetAccessor)

不幸的是,我的谷歌fu让我失望了。有什么想法吗?

我想你可以尝试使用扩展方法:
我不知道有什么巫术。您也许可以剥离
集合
,查找具有该名称的属性,并将
MethodInfo
实例(
invocation.Method
)与属性访问器(
GetSetMethod()
)进行比较-但是,我不能诚实地说(不检查)您是否会得到相同的
MethodInfo
实例(即使是相同的方法)


首先,您可以检查
MethodInfo
类的
MemberType
属性,查看它是否是
属性

现在,您应该尝试猜测它是get还是集合。如果您不想分析名称(有人可能会将方法命名为“set\u Something”),那么您可以检查参数

  • 如果属性访问器接受一个参数并返回
    void
    这是一套
  • 如果属性访问器返回一个值而不选择参数,它是一个get

您可能只对对象中的第一个检查感兴趣,即获取属性,该属性应表示这是一个,因此您应该能够将其强制转换为。该对象公开属性,该属性告诉您这是否是一个setter。

您可以检查是否存在此方法为setter的属性(未测试):


(灵感来源于)

我不确定invocation.Method是什么类型的,但是如果您可以获取PropertyInfo,您可以使用。不幸的是,这不仅可以告诉您属性是set或get,还可以告诉您它是否是重载运算符。

谢谢,但这就是我当前的解决方案的工作方式。我正在寻找一个不需要我的应用程序知道关于C#编译器实现细节。他可以使用扩展方法将
IsPropertySetAccessor
方法添加到
MethodInfo
类型中,但问题是该方法中的内容比他现在的要好。“我不喜欢我的代理对属性的实现方式了如指掌。”这个答案是毫无帮助的——这个问题似乎更多地指向了“一个方法中会有什么来确定这个”这一点,只是出于好奇而问。那么这个呢[]运算符?我认为它允许一个参数。属性访问器方法的
MemberType
MemberTypes.method
而不是
MemberTypes.property
。无论如何,谢谢。@dowhilefor:好的一点!!!你能在Reflector/ILDASM中看到结果并告诉我们吗?我在h没有同时具有此访问器的Reflector和程序集而且,但是mscorlib.dll应该是满的。嗯,文档似乎暗示
MemberType
将是
MemberTypes.Method
对象的
MethodInfo
方法。嗯,你是对的,我忽略了这一点,希望它是MemberTypes.Property为属性创建的MethodInfo对象,可能我不确定nymore现在我刚刚运行了一个测试:属性访问器方法的
MemberType
MemberTypes.method
而不是
MemberTypes.property
,所以它不会飞行。无论如何,谢谢。看起来非常inneficient@thepirat000:如果
GetSetMethod
为O(1),则为O(n)。这可能不是最优的(我肯定会支持任何可读性和性能都更好的备选答案),但我相信你知道过早优化是万恶之源的说法……我建议你检查该方法是否有“get_uu”前缀(区分大小写),并将其从方法集合中删除(仍然是O(n)复杂度-这相当便宜)。此外,您可以添加
字典
实例来保存已检查的类型,这些类型首先为您提供O(n)的复杂度,但之后为O(1)
if(method.IsSpecialName && method.Name.StartsWith("set_"))
{
    var prop = typeof (Foo).GetProperty(method.Name.Substring(4),
           BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    var accessor = prop.GetSetMethod();
    bool isSame = accessor == method;
}
bool isSetAccessor = invocation.Method.DeclaringType.GetProperties() 
        .Any(prop => prop.GetSetMethod() == invocation.Method)