在C#中,我们可以非常自由的、毫无限制的访问公有字段,但在一些场合中,我们可能希望限制只能给字段赋于某个范围的值、或是要求字段只能读或只能写,或是在改变字段时能改变对象的其他一些状态,这些单靠字段是无法做到的,于是就有了属性,属性中包含两个块:set和get,set块负责属性的写入工作,get块负责属性的读取工作。在两个块中都可以做一些其他操作,如在set中验证赋的值是否符合要求并决定是否进行赋值。当缺少其中一块时属性就只能读或只能写,set和get块中属性必需有一个,因为即不能读又不能写的属性是没有意义的。
classMyClass
{
Private string name;
publicstring Name
{
get {return Name;}
set {Name=value;}
}
}
(1)属性可以保证安全,当不在本类中使用时可以保证使用属性名可以避免用字段的名字。
(2)属性的set和get函数可以限制字段的一些功能,以达到某种目的。
如:
privateint a=0;
publicint A
{
get{return this.a;}
set
{
if(value >= 0 && value <= 100)
this.a=value;
else
throw new Exception("值的范围不合法。");
}
}
(3)属性没有存储数据的功能,数据都存在字段中,所以只有修改字段的数据才能更改数据,修改属性的值没用。
(4)属性的访问修饰符。(转自MSDN)
属性或索引器的 get 和 set 部分称为“访问器”。默认情况下,这些访问器具有相同的可见性或访问级别:其所属属性或索引器的可见性或访问级别。有关更多信息,请参见可访问性级别。不过,有时限制对其中某个访问器的访问会很有用。通常是在保持 get 访问器可公开访问的情况下,限制 set 访问器的可访问性。例如:
C#
publicstring Name
{
get
{
returnname;
}
protected set
{
name = value;
}
}
在此示例中,名为 Name 的属性定义了一个 get 访问器和一个 set 访问器。get 访问器接受该属性本身的可访问性级别(在此示例中为 public),而对于 set 访问器,则通过对该访问器本身应用 protected 访问修饰符来进行显式限制。
不能对接口或显式接口成员实现使用访问器修饰符。
仅当属性或索引器同时具有 set 和 get 访问器时,才能使用访问器修饰符。这种情况下,只允许对其中一个访问器使用修饰符。
如果属性或索引器具有 override 修饰符,则访问器修饰符必须与重写的访问器的访问器(如果有的话)匹配。
访问器的可访问性级别必须比属性或索引器本身的可访问性级别具有更严格的限制。
在重写属性或索引器时,被重写的访问器对重写代码而言,必须是可访问的。此外,属性/索引器和访问器的可访问性级别都必须与相应的被重写属性/索引器和访问器匹配。例如:
C#
publicclass Parent
{
public virtual int TestProperty
{
// Notice the accessor accessibilitylevel.
protected set { }
// No access modifier is used here.
get { return 0; }
}
}
publicclass Kid : Parent
{
public override int TestProperty
{
// Use the same accessibility level asin the overridden accessor.
protected set { }
// Cannot use access modifier here.
get { return 0; }
}
}
使用访问器实现接口时,访问器不能具有访问修饰符。但是,如果使用一个访问器(如 get)实现接口,则另一个访问器可以具有访问修饰符,如下面的示例所示:
C#
publicinterface ISomeInterface
{
int TestProperty
{
// No access modifier allowed here
//because this is an interface.
get;
}
}
publicclass TestClass : ISomeInterface
{
public int TestProperty
{
// Cannot use access modifier herebecause
// this is an interface implementation.
get { return 10; }
// Interface property does not have setaccessor,
// so access modifier is allowed.
protected set { }
}
}
如果对访问器使用访问某个修饰符,则访问器的可访问性域由该修饰符确定。
如果不对访问器使用访问修饰符,则访问器的可访问性域由属性或索引器的可访问性级别确定。
下面的示例包含三个类:BaseClass、DerivedClass 和 MainClass。每个类的 BaseClass、Name 和 Id 都有两个属性。该示例演示在使用限制性访问修饰符(如 protected或 private)时,如何通过 BaseClass 的 Id 属性隐藏 DerivedClass 的 Id 属性。因此,向该属性赋值时,将调用 BaseClass 类中的属性。将访问修饰符替换为 public将使该属性可访问。
该示例还演示 DerivedClass 的 Name 属性的 set 访问器上的限制性访问修饰符(如 private 或 protected)如何防止对该访问器的访问,并在向它赋值时生成错误。
C#
publicclass BaseClass
{
private string name = "Name-BaseClass";
private string id = "ID-BaseClass";
public string Name
{
get { return name; }
set { }
}
public string Id
{
get { return id; }
set { }
}
}
publicclass DerivedClass : BaseClass
{
private string name = "Name-DerivedClass";
private string id = "ID-DerivedClass";
new public string Name
{
get
{
return name;
}
// Using "protected" wouldmake the set accessor not accessible.
set
{
name = value;
}
}
// Using private on the following propertyhides it in the Main Class.
// Any assignment to the property will useId in BaseClass.
new private string Id
{
get
{
return id;
}
set
{
id = value;
}
}
}
classMainClass
{
static void Main()
{
BaseClass b1 = new BaseClass();
DerivedClass d1 = new DerivedClass();
b1.Name = "Mary";
d1.Name = "John";
b1.Id = "Mary123";
d1.Id = "John123"; // The BaseClass.Id property is called.
System.Console.WriteLine("Base:{0}, {1}", b1.Name, b1.Id);
System.Console.WriteLine("Derived:{0}, {1}", d1.Name, d1.Id);
}
}
Name and ID in the base class: Name-BaseClass, ID-BaseClass
Nameand ID in the derived class: John, ID-BaseClass
注意,如果将 new private string Id 替换为 newpublic string Id,则得到如下输出:
Nameand ID in the base class: Name-BaseClass, ID-BaseClass
Nameand ID in the derived class: John, John123