属性的定义:属性是一个声明的附加声明属性是这样的成员:它提供灵活的机制来读取、编写或计算某个私有字段的值。可以像使用公共数据成员一样使用属性,但实际上它们是称作“访问器”的特殊方法。这使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性。
属性结合了字段和方法的多个方面。对于对象的用户,属性显示为字段,访问该属性需要相同的语法。对于类的实现者,属性是一个或两个代码块,表示一个get 访问器和/或一个set 访问器。当读取属性时,执行get 访问器的代码块;当向属性分配一个新值时,执行 set 访问器的代码块。不具有set 访问器的属性被视为只读属性。不具有 get 访问器的属性被视为只写属性。同时具有这两个访问器的属性是读写属性。
与字段不同,属性不作为变量来分类。因此,不能将属性作为 ref(C# 参考)参数或out(C# 参考)参数传递。
属性具有多种用法:它们可在允许更改前验证数据;它们可透明地公开某个类上的数据,该类的数据实际上是从其他源(例如数据库)检索到的;当数据被更改时,它们可采取行动,例如引发事件或更改其他字段的值。
属性在类块中是按以下方式来声明的:指定字段的访问级别,接下来指定属性的类型和名称,然后跟上声明 get 访问器和/或set 访问器的代码块。例如:
public class Date
{
private int month = 7; // Backing store
public int Month
{
get
{
return month;
}
set
{
if ((value > 0) && (value < 13))
{
month = value;
}
}
}
}
在 C# 3.0 和更高版本中,当属性的访问器中不需要其他逻辑时,自动实现的属性可使属性声明更加简洁。客户端代码还可通过这些属性创建对象。如下面的示例所示声明属性时,编译器将创建一个私有的匿名支持字段,该字段只能通过属性的get 和 set 访问器进行访问。
// Auto-Impl Properties for trivial get and set
此示例演示如何创建一个不可变轻量类,用于仅封装一组自动实现的属性。当您必须使用引用类型语义时,请使用此种构造而不是结构。
请注意:对于自动实现的属性,需要 get 和 set 访问器。要使该类不可变,请将 set 访问器声明为private。但是,声明私有set 访问器时,不能使用对象初始值来初始化属性。必须使用构造函数或工厂方法。
下面的示例演示两种方法来实现具有自动实现属性的不可变类。第一个类使用构造函数初始化属性,第二个类使用静态工厂方法。
// This class is immutable. After an object is created,
// it cannot be modified from outside the class. It uses a
// constructor to initialize its properties.
class Contact
{
// Read-only properties.
public string Name { get; private set; }
public string Address { get; private set; }
// Public constructor.
public Contact(string contactName, string contactAddress)
{
Name = contactName;
Address = contactAddress;
}
}
// This class is immutable. After an object is created,
// it cannot be modified from outside the class. It uses a
// static method and private constructor to initialize its properties.
public class Contact2
{
// Read-only properties.
public string Name { get; private set; }
public string Address { get; private set; }
// Private constructor.
private Contact2(string contactName, string contactAddress)
{
Name = contactName;
Address = contactAddress;
}
// Public factory method.
public static Contact2 CreateContact(string name, string address)
{
return new Contact2(name, address);
}
}
public class Program
{
static void Main()
{
// Some simple data sources.
string[] names = {"Terry Adams","Fadi Fakhouri", "Hanying Feng",
"Cesar Garcia", "Debra Garcia"};
string[] addresses = {"123 Main St.", "345 Cypress Ave.", "678 1st Ave",
"12 108th St.", "89 E. 42nd St."};
// Simple query to demonstrate object creation in select clause.
// Create Contact objects by using a constructor.
var query1 = from i in Enumerable.Range(0, 5)
select new Contact(names[i], addresses[i]);
// List elements cannot be modified by client code.
var list = query1.ToList();
foreach (var contact in list)
{
Console.WriteLine("{0}, {1}", contact.Name, contact.Address);
}
// Create Contact2 objects by using a static factory method.
var query2 = from i in Enumerable.Range(0, 5)
select Contact2.CreateContact(names[i], addresses[i]);
// Console output is identical to query1.
var list2 = query2.ToList();
// List elements cannot be modified by client code.
// CS0272:
// list2[0].Name = "Eugene Zabokritski";
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}