`

.Net/C# 实现真正的只读属性 (ReadOnly Property)

 
阅读更多

/*

.Net/C# 实现真正的只读属性 (ReadOnly Property)

当类的私有成员是简单类型时,只需为该成员提供 public { get; } 的访问器即可实现只读属性。

当类的私有成员不是简单类型(如: ArrayList、Hashtable 等)时,
如果仅为该成员提供 public { get; } 的访问器而实现只读属性是远远不够的!
因为该属性 ArrayList、Hashtable 还可以被执行 Add(..)、Clear()、Remove(...) 等方法!

经 【身披七彩祥云 脚踏金甲圣衣】的 "思归 Saucer" 点拨,
参阅 Reflector: ArrayList.ReadOnly(...) static Method
搞定 ReadOnlyHashtable !

*/

//using System;
//using System.Collections;
//using System.Runtime.Serialization;

namespace Microshaoft
{
public class WithReadOnlyPropertyClass
{
public WithReadOnlyPropertyClass()
{
this._Hashtable = new System.Collections.Hashtable();
this._Hashtable.Add("1", "aaa");
this._Hashtable.Add("2", "bbb");
this._Hashtable.Add("3", "ccc");

this._ArrayList = new System.Collections.ArrayList();
this._ArrayList.Add("1");
this._ArrayList.Add("2");
this._ArrayList.Add("3");
}

private System.Collections.ArrayList _ArrayList;
public System.Collections.ArrayList ReadOnlyArrayList
{
get
{
//.Net Framework 已经实现
return System.Collections.ArrayList.ReadOnly(this._ArrayList);
}
}

private System.Collections.Hashtable _Hashtable;
public System.Collections.Hashtable ReadOnlyHashTable
{
get
{
return ReadOnlyHashtable.ReadOnly(this._Hashtable);
}
}

//.Net Framework 懒得实现 ReadOnlyHashtable ???
private class ReadOnlyHashtable : System.Collections.Hashtable
{
//《Refactoring: Improving the Design of Existing Code》
// 3.21 Refused Bequest: Replace Inheritance with Delegation
//如果不想修改superclass,还可以运用 Replace Inheritance with Delegation 来达到目的。
//也就是以委托取代继承,在 subclass 中新建一个 Field 来保存 superclass 对象,
//去除 subclass 对 superclass 的继承关系,委托或调用 superclass 的方法来完成目的。
//这里的委托不是 .Net 的 Delegation !
//仅仅就是代理人、替代品、代表的意思!
private System.Collections.Hashtable _Hashtable;

private ReadOnlyHashtable(System.Collections.Hashtable Hashtable)
{
this._Hashtable = Hashtable;
}

public static System.Collections.Hashtable ReadOnly(System.Collections.Hashtable Hashtable)
{
if (Hashtable == null)
{
throw new System.ArgumentNullException("Hashtable");
}
//多态
return new ReadOnlyHashtable(Hashtable);
}

private string _s = "集合是只读的。";

//重写 override 所有 "写" 操作的方法,运行时错误,如调用该方法则抛出异常
public override void Add(object key, object value)
{
throw new System.NotSupportedException(this._s);
}

public override void Clear()
{
throw new System.NotSupportedException(this._s);
}

public override object Clone()
{
ReadOnlyHashtable roht = new ReadOnlyHashtable(this._Hashtable);
roht._Hashtable = (System.Collections.Hashtable) this._Hashtable.Clone();
return roht;
}

//重写 override 方法
public override bool Contains(object key)
{
//用代理的 Hashtable Field 对象的实例方法重写
//return base.Contains(key);
return this._Hashtable.Contains(key);
}

public override bool ContainsKey(object key)
{
return this._Hashtable.ContainsKey(key);
}

public override bool ContainsValue(object value)
{
return this._Hashtable.ContainsValue(value);
}

public override void CopyTo(System.Array array, int arrayIndex)
{
this._Hashtable.CopyTo(array, arrayIndex);
}

public override System.Collections.IDictionaryEnumerator GetEnumerator()
{
//经重写改为调用代理成员对象的同名实例方法
return this._Hashtable.GetEnumerator();
}

//protected override int GetHash(object key)
//{
////protected 成员不能通过代理对象的实例方法重写
//return base.GetHash(key);
//}
//
//protected override bool KeyEquals(object item, object key)
//{
//return base.KeyEquals(item, key);
//}

public override void Remove(object key)
{
throw new System.NotSupportedException(this._s);
}

public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
this._Hashtable.GetObjectData(info, context);
}

public override void OnDeserialization(object sender)
{
this._Hashtable.OnDeserialization(sender);
}

public override bool IsReadOnly
{
get
{
return this._Hashtable.IsReadOnly;
}
}

public override bool IsFixedSize
{
get
{
return this._Hashtable.IsFixedSize;
}
}

public override bool IsSynchronized
{
get
{
return this._Hashtable.IsSynchronized;
}
}

public override System.Collections.ICollection Keys
{
get
{
return this._Hashtable.Keys;
}
}

public override System.Collections.ICollection Values
{
get
{
return this._Hashtable.Values;
}
}

public override object SyncRoot
{
get
{
return this._Hashtable.SyncRoot;
}
}

public override int Count
{
get
{
return this._Hashtable.Count;
}
}

//索引器别忘了重写 override
public override object this[object key]
{
get
{
//使用 代理对象
return this._Hashtable[key];
}
set
{
throw new System.NotSupportedException(this._s);
}
}
}
}
}

class AppTest
{
static void Main(string[] args)
{
Microshaoft.WithReadOnlyPropertyClass x = new Microshaoft.WithReadOnlyPropertyClass();

System.Console.WriteLine("ReadOnlyArrayList Property Test:");
//多态
System.Collections.ArrayList al = x.ReadOnlyArrayList;
foreach (object o in al)
{
System.Console.WriteLine("Value: {0}", o);
}
System.Console.WriteLine();
System.Collections.IEnumerator ie = al.GetEnumerator();
while (ie.MoveNext())
{
System.Console.WriteLine("Value: {0}", ie.Current);
}

System.Console.WriteLine("按/"y/"健,执行下面写操作将抛出异常,按其他健跳过写操作继续:");
if (System.Console.ReadLine().ToLower() == "y")
{
System.Console.WriteLine("抛出异常...");
al.Clear();
}

System.Console.WriteLine("/nReadOnlyHashTable Property Test:");
//多态
System.Collections.Hashtable ht = x.ReadOnlyHashTable;
foreach (System.Collections.DictionaryEntry e in ht)
{
System.Console.WriteLine("Key: {0} , Value: {1}", e.Key, e.Value);
}
System.Console.WriteLine();
System.Collections.IDictionaryEnumerator ide = ht.GetEnumerator();
while (ide.MoveNext())
{
System.Console.WriteLine("Key: {0} , Value: {1}", ide.Key, ide.Value);
}
System.Console.WriteLine("按/"y/"健,执行下面写操作将抛出异常,按其他健跳过写操作继续:");
if (System.Console.ReadLine().ToLower() == "y")
{
System.Console.WriteLine("抛出异常...");
ht.Clear();
}
System.Console.ReadLine();
}
}

分享到:
评论

相关推荐

    .NET/C#实现识别用户访问设备的方法

    本文实例讲述了.NET/C#实现识别用户访问设备的方法。分享给大家供大家参考,具体如下: 一、需求 需要获取到用户访问网站时使用的设备,根据不同设备返回不同类型的渲染页面。 二、实现前准备 通过NuGet把UAParser...

    使用openFileDialog和saveFileDialog打开和保存*.rtf文件的应用实例,如果在openFileDialog1中选定文件为只读方式打开,那么ReadOnly属性设置为true,在richTextBox1中不能修改文本,C#源代码

    使用openFileDialog和saveFileDialog打开和保存*.rtf文件的应用实例,如果在openFileDialog1中选定文件为只读方式打开,那么ReadOnly属性设置为true,在richTextBox1中不能修改文本,C#源代码 用VisualStudio2008创建 ...

    C#实现的数值编辑框控件TNumEditBox(V1.3)

    C#实现的数值编辑框控件TNumEditBox(V1.3),具有功能:1)设置ReadOnly时的背景颜色;2)定义小数位长;3)允许非负数;4)支持Ctrl+V/Ctrl+C/Ctrl+X等快捷键操作;5)支持鼠标上下文菜单操作(Paste/Copy/Cut)。...

    RAMAN特性参数(一)exclude/skip readonly/只读表空间备份恢复

    最近做只读表空间备份策略的时候,重新温习了下RMAN的相关特性和只读表空间的备份恢复方法,写成文档记录目录如下 RMAN特性参数 1 RMAN EXCLUDE 2 RMAN EXCLUDE基础命令 2 RMAN EXCLUDE备份 3 RMAN EXCLUDE恢复 6 ...

    php.ini-development

    http://php.net/configuration.file ; The syntax of the file is extremely simple. Whitespace and lines ; beginning with a semicolon are silently ignored (as you probably guessed). ; Section headers (e...

    C#中的只读结构体(readonly struct)详解

    翻译自 John Demetriou 2018年4月8日 的文章 《C# 7.2 – Let’s Talk About Readonly Structs》[1] 在本文中,我们来聊一聊从 C# 7.2 开始出现的一个特性 readonly struct。 任一结构体都可以有公共属性、私有属性...

    TTXStringGrid组件V1.1.64源码包-delphi中的扩展StringGrid

    支持列设置,包括字体,颜色,居中,列宽,visible,readonly, 内置下拉列表, 右键菜单; 增加一系列事件,如CellClick等. V1.1新增功能:增加对单元格的个性化设置,效果和列个性化设置类似。 Lonefox版权所有. 技术交流 ...

    c#.net中const和readonly的区别

    readonly修饰符用来表示只读,const用来表示不变常量。顾名思义,只读表示不能进行写操作;不变常量不能被修改。这两者到底有什么区别呢

    原创词云图制作小工具代码

    该款小工具使用python创作,可以自主...Entry(root, textvariable=inpath0,state="readonly",width=15).grid(row=2, column=2,ipadx=150)#ipadx是条形框长度 Button(root, text="输入路径选择", width=15,height=1,co

    数据库的通用访问代码 asp.net(C#语言)

    public static readonly string SqlConn = ConfigurationManager.ConnectionStrings["SqlConn"].ConnectionString; // 哈希表用来存储缓存的参数信息,哈希表可以存储任意类型的参数。 private static Hashtable...

    浅谈html中input只读属性readonly和disable的区别

    下面小编就为大家带来一篇浅谈html中input只读属性readonly和disable的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    局域网进程管理系统源码

    public readonly DateTime TerminationDate; /// /// 进程的图标,无图标时为 null. /// </summary> public readonly System.Drawing.Icon ICon; /// /// 进程的说明. /// </summary> public ...

    Mycat实现mysql主从读写分离的配置文件

    这是Mycat实现mysql主从读写分离时用到的的配置文件。 内容包括:schema.xml和server.xml。 ... 相关操作教程:... <property name="readOnly">true</property> </user>

    设置checkbox为只读(readOnly)的两种方式

    方式一: checkbox没有readOnly属性,如果使用disabled=“disabled”属性的话,会让checkbox变成灰色的,用户很反感这种样式可以这样让它保持只读: 设置它的onclick=”return false” js里就是 checkbox.onclick=...

    jquery批量设置属性readonly和disabled的方法

    Jquery的api中提供了对元素应用...//去除input元素的readonly属性 if($(‘input’).attr(“readonly”)==true)//判断input元素是否已经设置了readonly属性 对于为元素设置readonly属性和取消readonly属性的方法还有如

    c#中const与readonly区别

    c#中const与readonly区别

    通用商城系统 v3.0

    演示地址:http//shop.lantou.net/admin 帐号密码都是:readonly通用商城系统安装使用说明1、通用商城系统版本说明:通用商城系统V3.0分为免费版和正式版。免费版和正式版再各自分为:URL地址优化版、原始版本。...

    asp.net知识库

    实现C#和VB.net之间的相互转换 深入剖析ASP.NET组件设计]一书第三章关于ASP.NET运行原理讲述的补白 asp.net 运行机制初探(httpModule加载) 利用反射来查看对象中的私有变量 关于反射中创建类型实例的两种方法 ASP...

    .net中const和readonly使用

    分别解说了C#中const的使用方法和readonly的使用方法和区别

Global site tag (gtag.js) - Google Analytics