[C#参考]属性

属性和字段不同,属性是一个函数成员:它提供灵活的机制来读取、编写或计算某个私有字段的值。 可以像使用公共数据成员一样使用属性,但实际上它们是称作“访问器”的特殊方法。 这使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性。

属性不为数据存储分配内存空间,它是执行代码。

意思是如果我们想封装类的成员变量,但是我们总不能把所有的变量都封装的死死的,不允许外面的任何人看到,这是不合理的。

例如有一个person类,它的属性有姓名、性别、年龄等。我要访问某个对象的性别,或者设置某个对象的性别。

外部的对象要实现,对它的访问,有三种方法:

1.把属性改正public的权限,这样任何人都能看到或者修改这个属性,这样很简洁,但是出现的问题是安全性降低,比如我对这个字段赋值“牛”,那么这个对象的的性别字段就是“牛”了,显然不合理。

2.仍然保持字段的private私有属性,编写一个方法实现字段的修改,但是这样以来,外部对象访问内部私有对象的时候,很麻烦,必须调用set()或者get()方法。那么就寻求一种方法,能不公开私有字段,同时又能很简洁的调用,就好像是在直接访问成员字段一样,所以就引入了第三种方法:属性。

3.属性封装字段数据,对象的字段保持其private的访问权限,利用属性实现封装,好像直接访问成员字段一样供外部对象使用。但是本质上仍然是通过类的成员方法访问才实现的。属性也是类的成员,但是它是私有地段的封装,只是私有字段的一个对外的接口,它能通过一些逻辑保证私有字段访问的安全机制,同时又不会像第2种方法那样使用用户不友好的接口。能像直接访问私有字段一样访问。

在本示例中,TimePeriod 类存储一个时间段。 在内部,类以秒为单位存储时间,但客户端使用名为 Hours 的属性能够以小时为单位指定时间。 Hours 属性的访问器执行小时和秒之间的转换。

 1 class TimePeriod
 2 {
 3     private double seconds;
 4 
 5     public double Hours
 6     {
 7         get { return seconds / 3600; }
 8         set { seconds = value * 3600; }
 9     }
10 }
11 
12 
13 class Program
14 {
15     static void Main()
16     {
17         TimePeriod t = new TimePeriod();
18 
19         // Assigning the Hours property causes the 'set' accessor to be called.
20         t.Hours = 24;
21 
22         // Evaluating the Hours property causes the 'get' accessor to be called.
23         System.Console.WriteLine("Time in hours: " + t.Hours);
24     }
25 }
26 // Output: Time in hours: 24
View Code

 value 关键字用于定义由 set 取值函数分配的值。

我们可以设置访问修饰符限制get和set方法的访问权限,为此,属性必须既有set又有get访问方法,而且只能限制其中之一,修饰符必须必属性本身已有的访问权限要严格。

此示例演示如何创建一个不可变轻量类,用于仅封装一组自动实现的属性。 当您必须使用引用类型语义时,请使用此种构造而不是结构。

请注意:对于自动实现的属性,需要 get 和 set 访问器。 要使该类不可变,请将 set 访问器声明为 private。 但是,声明私有 set 访问器时,不能使用对象初始值来初始化属性。 必须使用构造函数或工厂方法。

 1  // This class is immutable. After an object is created,
 2     // it cannot be modified from outside the class. It uses a
 3     // constructor to initialize its properties.
 4     class Contact
 5     {
 6         // Read-only properties.
 7         public string Name { get; private set; }
 8         public string Address { get; private set; }
 9 
10         // Public constructor.
11         public Contact(string contactName, string contactAddress)
12         {
13             Name = contactName;
14             Address = contactAddress;               
15         }
16     }
17 
18     // This class is immutable. After an object is created,
19     // it cannot be modified from outside the class. It uses a
20     // static method and private constructor to initialize its properties.   
21     public class Contact2
22     {
23         // Read-only properties.
24         public string Name { get; private set; }
25         public string Address { get; private set; }
26 
27         // Private constructor.
28         private Contact2(string contactName, string contactAddress)
29         {
30             Name = contactName;
31             Address = contactAddress;               
32         }
33 
34         // Public factory method.
35         public static Contact2 CreateContact(string name, string address)
36         {
37             return new Contact2(name, address);
38         }
39     }
View Code

 前面说了,属性只是封装数据字段,编译器为每个自动实现的属性创建了后备字段 这些字段无法直接从源代码进行访问。

posted @ 2014-11-13 20:20  stemon  阅读(197)  评论(0编辑  收藏  举报