什么是PropertyInfo中的CanRead和CanWrite的含义?

5

我正在编写一个类,根据属性的可访问性生成WPF绑定。以下是关键方法:

static Binding getBinding(PropertyInfo prop)
{
    var bn = new Binding(prop.Name);
    bn.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
    if (prop.CanRead && prop.CanWrite)
        bn.Mode = BindingMode.TwoWay;
    else if (prop.CanRead)
        bn.Mode = BindingMode.OneWay;
    else if (prop.CanWrite)
        bn.Mode = BindingMode.OneWayToSource;
    return bn;
}

然而,这并没有按照预期的方式工作。当它应该为false时,CanWrite 却是 true。例如,对于此属性:
abstract class AbstractViewModel {
    public virtual string DisplayName { get; protected set; }
}

class ListViewModel : AbstractViewModel {
    //does not override DisplayName
}

我发现 ListViewModelDisplayName 属性既可以读取也可以写入 (CanReadCanWrite)。然而,如果我调用 prop.GetAccessors(),只有 get_DisplayName() 访问器被列出。

这是怎么回事?如果不是属性的保护级别,CanReadCanWrite 表示什么?我的方法应该如何正确实现?

嗯,让我们从一个事实开始,AbstractViewModel并不是抽象的...... 说了这个,我认为你不能指望从一个不正确的实现(虚拟但没有派生实现)中获得确定性行为。 - user694833
我认为你真正想问的是:如何检查可访问的getter和setter,对吗?如果是这样,Jon Skeet在这里回答了这个问题:https://dev59.com/znVC5IYBdhLWcg3wbQXA#302492 - Craig O
@JaimieOlivares 虚拟方法和属性不必被覆盖。可选择性地覆盖它们。不过你说的没错,AbstractViewModel 在我的应用程序中实际上是声明为抽象的...我会编辑问题。 - Oliver
1个回答

18
如果你有像这样的问题,首先应该查看文档。CanRead: 如果属性没有 get 访问器,则无法读取该属性。CanWrite: 如果属性没有 set 访问器,则无法写入该属性。因此,这些属性指示是否存在 get set 访问器,而不是它们的保护级别。其中一个原因是Reflection不知道您从何处调用它,因此它不知道您实际上是否可以访问访问器。
你可以通过调用GetGetMethod()GetSetMethod()方法来查找是否可以访问访问器。如果属性没有公共的get/set访问器,它们将返回null

我明白了。你说反射不知道它被哪里调用,但它设法找出从调用位置可见的访问器,所以我认为CanReadCanWrite的定义有点奇怪。感谢你的回答。 - Oliver
@Oliver - 不完全是。所有“CanWrite”在说的就是有一个setter。 - ChrisF
1
@Oliver,如果你的意思是 GetAcessors() 只返回你可访问的访问器,那么这是不正确的。再次阅读文档,你会发现它总是只返回公共访问器,即使你能够访问更多访问器。 - svick

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