一周学会C#(属性一)

一周学会 C# (属性一)

C# 才鸟( QQ:249178521 )

1. 问题

  • ** 原始的封装是麻烦的 ** ** **

** struct Time **

** { **

** ... **

** public int GetHour() **

** { **

** return hour; **

** } **

** public void SetHour(int value) **

** { **

** hour = value; **

** } **

** ... **

** private int hour, minute, second; **

** } **

** static void Main () **

** { **

** Time lunch = new Time(); **

** lunch.SetHour(12); **

** Console.WriteLine(lunch.GetHour()); **

** } **

封装把一些不重要的细节隐藏起来,这样你可以集中精力处理那些重要的内容。但封装很难被掌握,一个典型的封装误用是盲目地把公有字段转为私有字段。例如在上面的例子中,程序定义了一个私有字段 hour 和 SetHour 函数和 GetHour 函数,而不是定义一个公有的 hour 字段。如果 GetHour 函数只是返回私有字段的值而 SetHour 函数只是设置私有字段的值的话,那么你除了使 Time 类更难使用外,你不会得到任何好处。

2. 不是解决的办法

· ** 如果字段是公有的,那使用起来是简单的 ** ** **

w ** 但如果你使用公有字段的话,你会失去控制权 ** ** **

w ** 要简化而不是简单 ** ** **

** struct Time **

** { **

** ... **

** public int Hour; **

** public int Minute; **

** public int Second; **

** } **

** static void Main () **

** { **

** Time lunch = new Time(); **

** lunch.Hour = 30; **

** lunch.Minute = 12; **

** lunch.Second = 0; **

** ... **

** } **

上面的例子使用公有字段来使字段的使用比较简单。例如,你不用写:

lunch.SetHour(lunch.GetHour() + 1);

而只要写:

++lunch.Hour;

但是,这种简单的表达式是有代价的。考虑上面的例子,程序给 Hour 和 Minute 字段分别赋值为 30 和 12 。问题是 30 不在 Hour 的范围( 0-23 )内。但如果字段是公有的话,你就没有办法捕获这个错误。

所以虽然 get 和 set 函数比较麻烦,但它们在这方面比公有字段具有优势是很明显的。 get 和 set 函数允许程序员控制类的内在字段的读和写。这是非常有用的,例如你可以检查 set 函数的参数范围。

当然最理想的方法是保留公有字段提供的简单而直接的表达式和 get 和 set 函数提供的控制权。(呵呵,人总是既想偷懒又想得到很多)

3. 解决的办法

· ** 属性 ** ** **

w ** 自动使用 ** **_ get _ ** ** ** ** 标识符进行读 ** ** **

w ** 自动使用 ** ** set ** ** 标识符进行写 ** ** **

** struct Time **

** { **

** ... **

** public int Hour // ** ** 没有(),是 ** ** H ** ** 而不是 ** ** h **

** { **

** get { ... } **

** set { ... } **

** } **

** private int hour, minute, second; **

** } **

** Time lunch = new Time(); **

** ... **

** lunch.Hour = 12; **

** ... **

** Console.WriteLine(lunch.Hour); **

C# 提供了一个解决上述问题的好办法。你可以把 get 和 set 函数组合成一个简单的属性。属性的声明包括一个可选的访问修饰符 ( 在例子中是 public) 、返回值 (int) 、属性的名字 (Hour) 和一个包含 get 和 set 语句的属性体。特别要注意的是属性没有括号,因为属性不是函数。属性的命名规则应符合一般的命名规则,即公有的使用 PascalCase 规则,而非公有的使用 camelCase 规则。在上面的例子中, Hour 属性是公有的,所以命名为 Hour 而不是 hour 。

例子中演示了属性的用法。属性使用的语法和字段的一样,没有括号。如果你要写一个属性,那你可以这样写:

lunch.Hour = 12;

属性的 set 语句自动被执行。

如果你要读一个属性,你可以这样写:

int hour = lunch.Hour;

属性的 get 语句自动被执行。

4. get 语句

l **_ get _ ** **_ 语句 _ ** ** **

Ø ** 必须返回一个有确定类型的值 ** ** **

Ø ** 功能上就像一个 ** ** “get ** ** 函数 ** ** ” **

** struct Time **

** { **

** ... **

** public int Hour **

** { **

** get **

** { **

** return hour; **

** } **

** ... **

** } **

** private int hour, minute, second; **

** } **

** Time lunch = new Time(); **

** ... Console.WriteLine(lunch.Hour); **

** // ** ** 请注意, ** ** get ** ** 和 ** ** set ** ** 不是关键字 **

当读一个属性的时候,属性的 get 语句自动运行。

get 语句必须返回一个有确定类型的值。在上面的例子中, Time 结构类有一个整型属性 Hour ,所以它的 get 语句必须返回一个整型值。

属性的返回值不能是 void (从这里可以推断出字段的类型也不能是 void )。这就意味着 get 语句必须包含一个完整的 return 语句( retun; 这种形式是错误的)。

get 语句可以在 retun 语句前包含任何其他的语句(比如,可以检查变量的类型) , 但 return 语句不能省略。

注意, get 和 set 不是关键字,所以你可以在任何地方包括 get/set <SPAN style="FONT-FAMILY: 宋

Published At
Categories with Web编程
Tagged with
comments powered by Disqus