**************************************************************************
书名:《C#高效编程改进C#代码的50个行之有效的办法》
**************************************************************************
第1章 C#语言习惯/1
--------------------------------------------------------------
建议1: 使用属性而不是可访问的数据成员/ 1
--------------------------------------------------------------
该建议点主要介绍属性的特性以及索引器的使用。
使用建议:
1.无论何时需要在类型的公有或保护接口中暴露数据,都应该使用属性。
2.你也应该使用索引器来暴露序列或字典。
3.所有的数据成员都应该是私有的,没有任何例外。
本人测试代码:
1 /****************************************************************** 2 * 创 建 人: 王申和 3 * 创建时间: 2012-11-1 15:45 4 * 描 述: 5 * 测试属性相关功能:属性特性与索引器 6 * 环 境: VS2010 7 ******************************************************************/ 8 using System; 9 using System.Collections.Generic; 10 using System.Linq; 11 using System.Text; 12 using System.Threading; 13 14 namespace _01_UseProperty 15 { 16 class Program 17 { 18 static void Main(string[] args) 19 { 20 try 21 { 22 var c = new Customer<string>(); 23 //c.Name = null; 24 c.Text = "测试无字段属性"; 25 Console.WriteLine(c.Text); 26 27 //测试索引器 28 c[30] = "测试一维序列索引器"; 29 Console.WriteLine(c[30]); 30 Console.WriteLine(c[120]); 31 32 c["字典1"] = "测试字典索引器"; 33 Console.WriteLine("内容:" + c["字典2"]); 34 Console.WriteLine("内容:" + c["字典1"]); 35 36 Name name = new Name("王", "五"); 37 c[name] = "测试字典索引器:参数为类"; 38 Console.WriteLine("内容:" + c[name]); 39 40 c[10, 20, 30] = "测试多维序列索引器"; 41 Console.WriteLine("内容:" + c[10, 20, 30]); 42 43 c["张", "三"] = "测试多维字典索引器"; 44 Console.WriteLine("内容:" + c["张", "三"]); 45 46 c[2, "李四"] = "四个人才"; 47 Console.WriteLine("内容:" + c[2, "李四"]); 48 49 } 50 catch (ArgumentException ex) 51 { 52 Console.WriteLine(ex.Message); 53 } 54 Console.ReadLine(); 55 } 56 } 57 58 public class Customer<T> 59 { 60 #region 属性两种写法 61 //尽量不要使用可访问的数据成员,应使用属性 62 //public string text; 63 64 //无字段属性,等同于下面 65 public string Text { get; set; } 66 67 //有字段属性 68 //private string text; 69 //public string text 70 //{ 71 // get { return text; } 72 // set { text = value; } 73 //} 74 #endregion 75 76 #region 属性为方法,可加异常处理 77 private string name; 78 public string Name 79 { 80 get { return name; } 81 set 82 { 83 if (string.IsNullOrEmpty(value)) 84 throw new ArgumentException("Name cannot be blank", "Name"); 85 name = value; 86 } 87 } 88 #endregion 89 90 #region 属性支持interface、virtual、abstract(属性拥有方法的所有语言特性) 91 public interface INameValuePair<T> 92 { 93 string Name { get; } 94 T Value { get; set; } 95 } 96 97 public virtual string vtest 98 { 99 get; 100 protected set; 101 } 102 103 public abstract class AbsClass 104 { 105 public abstract string atest { get; set; } 106 } 107 #endregion 108 109 #region 支持多线程:访问器中增加锁 110 private object Sync = new object(); 111 private int count; 112 public int Count 113 { 114 get 115 { 116 lock (Sync) 117 return count; 118 } 119 set 120 { 121 lock (Sync) 122 count = value; 123 } 124 } 125 #endregion 126 127 #region 属性索引器 128 //1.索引器都使用this关键字声明。C#不支持为索引器命名 129 //2.索引器是属性的一种,它本质上和属性一样是方法。 130 //3.索引器可以重载,因此一个类中可以有多个索引器。 131 132 //一维序列索引器,注意索引器范围 133 string[] theValues = new string[100]; 134 public string this[int index] 135 { 136 get 137 { 138 if (index > 99) 139 return default(string); 140 return theValues[index]; 141 } 142 set { theValues[index] = value; } 143 } 144 145 //字典索引器 146 Dictionary<T, T> dic = new Dictionary<T, T>(); 147 public T this[T key] 148 { 149 get 150 { 151 if (!dic.ContainsKey(key)) 152 return default(T); 153 return dic[key]; 154 } 155 set { dic[key] = value; } 156 } 157 158 //字典索引器:参数为类 159 Dictionary<Name, T> dicClass = new Dictionary<Name, T>(); 160 public T this[Name key] 161 { 162 get 163 { 164 if (!dicClass.ContainsKey(key)) 165 return default(T); 166 return dicClass[key]; 167 } 168 set { dicClass[key] = value; } 169 } 170 171 //多维序列索引器 172 T[, ,] multArray = new T[100, 100, 100]; 173 public T this[int x, int y, int z] 174 { 175 get { return multArray[x, y, z]; } 176 set { multArray[x, y, z] = value; } 177 } 178 179 //多维字典索引:此处利用了结构体为值类型的特性。 180 struct PeopleName 181 { 182 public PeopleName(string fn, string ln) 183 : this() //结构体的构造函数重载需要调用默认构造函数 184 { 185 FirstName = fn; 186 LastName = ln; 187 } 188 public string FirstName { get; set; } 189 public string LastName { get; set; } 190 } 191 Dictionary<PeopleName, T> dicMult = new Dictionary<PeopleName, T>(); 192 public T this[string fn, string ln] 193 { 194 get 195 { 196 var pn = new PeopleName(fn, ln); 197 if (!dicMult.ContainsKey(pn)) 198 return default(T); 199 return dicMult[pn]; 200 } 201 set { dicMult[new PeopleName(fn, ln)] = value; } 202 } 203 204 //多维字段索引:采用嵌套(嵌套有很多种,如数组嵌套字典、字典嵌套字典、甚至可以嵌套类等等) 205 Dictionary<T, T>[] dics = new Dictionary<T, T>[100]; 206 public T this[int i, T key] 207 { 208 get 209 { 210 if (i>99 || !dics[i].ContainsKey(key)) 211 return default(T); 212 return dics[i][key]; 213 } 214 set 215 { 216 if (dics[i] == null) 217 dics[i] = new Dictionary<T, T>(); 218 dics[i][key] = value; 219 } 220 } 221 #endregion 222 } 223 224 public class Name 225 { 226 public Name(string fn, string ln) 227 { 228 FirstName = fn; 229 LastName = ln; 230 } 231 public string FirstName { get; set; } 232 public string LastName { get; set; } 233 } 234 }
作者:SamWang
出处:http://wangshenhe.cnblogs.com/
本文版权归作者和博客园共有,欢迎围观转载。转载时请您务必在文章明显位置给出原文链接,谢谢您的合作。