PropertyInfo.GetSetMethod(true)无法返回基类属性的方法

7
我有一个测试程序如下:

```

public class FooBase
{
  public object Prop {
    get { return null; }
    private set { } 
  }
}
public class Foo :FooBase
{
}
class Program
{
  static void Main(string[] args)
  {
    MethodInfo setMethod = typeof(Foo).GetProperty("Prop").GetSetMethod(true);
    if (setMethod==null)
      Console.WriteLine("NULL");
    else
      Console.WriteLine(setMethod.ToString());
    Console.ReadKey(); 
  }
}

如果我运行它,它会显示“NULL”。如果我将属性定义移动到Foo类中,则会按预期工作。这是.NET中的一个错误吗?

请解释下投反对票的原因,这是一个合法的问题。 - Nix
1
我修改了标题。永远不要期望出现错误,而是怀疑自己的理解,并制作可读性强的问题标题,以便其他人能够理解问题是否对他们有趣。顺便说一句:我没有投反对票,但我猜测这可能与标题有关。 - Emond
抱歉标题不够清楚。但是你的也不正确。我已经改成正确的了。 - Denis Bredikhin
3个回答

8
您可以通过获取属性所声明类型的 PropertyInfo 来实现此目的,简单的扩展方法可能是...
public static class Extensions
{
   public static MethodInfo GetSetMethodOnDeclaringType(this PropertyInfo propertyInfo)
   {
       var methodInfo = propertyInfo.GetSetMethod(true);
       return methodInfo ?? propertyInfo
                               .DeclaringType
                               .GetProperty(propertyInfo.Name)
                               .GetSetMethod(true);
   }
}

那么你的调用代码需要...

class Program
{
    static void Main(string[] args)
    {
       MethodInfo setMethod = typeof(Foo)
                                 .GetProperty("Prop")
                                 .GetSetMethodOnDeclaringType();
       if (setMethod == null)
            Console.WriteLine("NULL");
        else
            Console.WriteLine(setMethod.ToString());
         Console.ReadKey();
    }
}

5

这是有意为之的。无论你尝试什么,Foo类中都无法访问FooBase属性的setter方法:

public class Foo : FooBase {
    void Test() {
        Prop = new object();  // No
        ((FooBase)this).Prop = new object();  // No
    }
}

您需要在代码中使用 typeof(FooBase).GetProperty("Prop")。


3

编辑

抱歉,

你在下面的评论中是正确的。错误是不同的。Foo类中没有设置方法,因此它没有返回方法。这是因为它在基类中是私有的。


1
不,GetProperty本身返回正确的值 - 否则这里会出现异常。GetSetMethod方法不返回有效值。 - Denis Bredikhin
GetSetMethod方法的布尔参数为true,这意味着应该返回私有setter。在MSDN关于GetSetMethod的文章中没有关于此方法与基本类型道具一起使用的说明。 - Denis Bredikhin
但是答案似乎是正确的,如果将可见性从private更改为protected,它就可以工作。你可以在Microsoft Connect上发布关于这个问题的帖子。 - Maximilian Mayerl
1
一个基类的私有方法在派生类中永远不可用,无论你传递什么布尔值。 - Emond

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