当前位置: 代码迷 >> C# >> 利用反射机制可否知道一个属性是否是只读的或者是只写的
  详细解决方案

利用反射机制可否知道一个属性是否是只读的或者是只写的

热度:14   发布时间:2016-05-05 03:23:39.0
利用反射机制能否知道一个属性是否是只读的或者是只写的?
例如我有一个接口的定义:

public interface IB
{
string name{get;} // can retrieve get or set permission?
}

我能否反射出这个接口IB当中的这个属性string name到底是不是只读的呢

为什么继承一个属性的时候,能把一个只读的属性变成一个可读可写的?

public interface IB
{
string name{get;} // can retrieve get or set permission?
}
class a:IB
{
public string _name;
public string name { get { return _name; } set { _name = value; } }
}

这个代码编译运行是没有问题的。但是我的问题是,既然接口里面是只读属性,相当于告诉我这个值,一旦设定了永远不会变,这相当于代码调用的一种"契约"
但是继承类里面去增加了一个set,相当于就是改变了这个契约,对吧。就好像是我用接口来写的一个算法,本来的设想是,这个属性不变,是一个程序中的不变量。

但是后来程序却发生了改变,属性变了,我之前程序里面的设定就无效了,这是一种"break change"吗?
谢谢。

------解决思路----------------------
这个问题其实提得挺不错的。

对接口的约束管得比较稀松,这可能是历史造成的。然后有太多的东西都已经是这样的,只能永远稀松下去。除非换一种语言。
------解决思路----------------------
关于”反射“,你可以这样写
var x = new a();
x.name = "Asf";
IB y = x;
var canWrite = y.GetType().GetProperty("name").CanWrite;


不过,我相信好的程序是非常规避反射的。一个上万行的程序,其中有10行代码直接用到反射就很”可以“了,其它代码要尽可能地基于接口、多态来设计。

那么当你基于多态来设计时,假设使用 IB 作为你的某段实际功能的处理对象的变量类型声明,那么编译器也就帮你“禁止写”。虽然对象的name属性还是可以写,但是需要“绕道”就增加了复杂度了。以这种编译时的“君子协定”方式来帮你“维系契约”。

所以我们还是强调,不要滥用反射。要用接口、多态等正规方式来设计扩展式的架构。
------解决思路----------------------
再“纯洁”的接口定义也只是一种协议,我们只能要求(希望)继承接口的程序设计者考虑到协定,但是你不可能因此就在运行时保证是只读的。例如代码
public interface IB
{
    string name { get; } // can retrieve get or set permission?
}
class a : IB
{
    public string _name;
    public string name { get { return _name; } }

    public void SetUserInfo(User usr)
    {
        ........其它各种处理
        _name = usr.name;
    }
}

这也是合理的。
------解决思路----------------------
引用:
但是我的问题是,既然接口里面是只读属性,相当于告诉我这个值,一旦设定了永远不会变,这相当于代码调用的一种"契约...


对接口的理解应该是英文中的able,即可怎么怎么。
接口中的string name{get;} 应该理解为读name属性,而不应该理解为读。
  相关解决方案