【笔记】《C#高效编程改进C#代码的50个行之有效的办法》第1章C#语言习惯(1)--属性的特性以及索引器(SamWang)

**************************************************************************

书名:《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/
本文版权归作者和博客园共有,欢迎围观转载。转载时请您务必在文章明显位置给出原文链接,谢谢您的合作。

posted on 2012-11-01 16:41  SamWang  阅读(2092)  评论(4编辑  收藏  举报