属性可以说是C#语言的一个创新。当然你也可以说不是。不是的原因是它背后的实现实际上还是两个函数–一个赋值函数(get),一个取值函数(set),这从它生成的中间语言代码可以清晰地看到。是的原因是它的的确确在语言层面实现了面向对象编程一直以来对“属性”这一OO风格的类的特殊接口的诉求。理解属性的设计初衷是我们用好属性这一工具的根本。C#不提倡将域的保护级别设为public而使用户在类外任意操作–那样太不OO,或者具体点说太不安全!对所有有必要在类外可见的域,C#推荐采用属性来表达。属性不表示存储位置,这是属性和域的根本性的区别。下面是一个典型的属性设计:
using System;
class MyClass
{
int integer;
public int Integer
{
get {return integer;}
set {integer=value;}
}
}
class Test
{
public static void Main()
{
MyClass MyObject=new MyClass();
Console.Write(MyObject.Integer);
MyObject.Integer++;
Console.Write(MyObject.Integer);
}
}
一如我们期待的那样,程序输出0 1。我们可以看到属性通过对方法的包装向程序员提供了一个友好的域成员的存取界面。这里的value是C#的关键字,是我们进行属性操作时的set的隐含参数,也就是我们在执行属性写操作时的右值。
属性提供了只读(get),只写(set),读写(get和 set)三种接口操作。对域的这三种操作,我们必须在同一个属性名下声明,而不可以将它们分离,看下面的实现:
class MyClass
{
private string name;
public string Name
{
get { return name; }
}
public string Name
{
set { name = value; }
}
}
上面这种分离Name属性实现的方法是错误的!我们应该像前面的例子一样将他们放在一起。值得注意的是三种属性(只读,只写,读写)被C#认为是同一个属性名,看下面的例子:
class MyClass
{
protected int num=0;
public int Num
{
set
{
num=value;
}
}
}
class MyClassDerived: MyClass
{
new public int Num
{
get
{
return num;
}
}
}
class Test
{
public static void Main()
{
MyClassDerived MyObject = new MyClassDerived();
//MyObject.Num= 1; //错误 !
((MyClass)MyObject).Num = 1;
}
}
我们可以看到MyClassDerived中的属性Num-get{}屏蔽了MyClass中属性Num-set{}的定义。
当然属性远远不止仅仅限于域的接口操作,属性的本质还是方法,我们可以根据程序逻辑在属性的提取或赋值时进行某些检查,警告等额外操作,看下面的例子:
class MyClass
{
private string name;
public string Name
{
get { return name; }
set
{
if (value==null)
name=”Microsoft”;
else
name=value;
}
}
}
由于属性的方法的本质,属性当然也有方法的种种修饰。属性也有5种存取修饰符,但属性的存取修饰往往为public,否则我们也就失去了属性作为类的公共接口的意义。除了方法的多参数带来的方法重载等特性属性不具备外, virtual, sealed, override, abstract等修饰符对属性与方法同样的行为,但由于属性在本质上被实现为两个方法,它的某些行为需要我们注意。看下面的例子:
abstract class A
{
int y;
public virtual int X
{
get { return 0; }
}
public virtual int Y
{
get { return y; }
set { y = value; }
}
public abstract int Z { get; set; }
}
class B: A
{
int z;
public override int X
{
get { return base.X + 1; }
}
public override int Y
{
set { base.Y = value < 0? 0: value; }
}
public override int Z
{
get { return z; }
set { z = value; }
}
}
这个例子集中地展示了属性在继承上下文中的某些典型行为。这里,类A由于抽象属性Z的存在而必须声明为abstract。子类B中通过base关键字来引用父类A的属性。类B中可以只通过Y-set便覆盖了类A中的虚属性。
静态属性和静态方法一样只能存取类的静态域变量。我们也可以像做外部方法那样,声明外部属性。
来源:http://blog.163.com/heng_future/blog/static/94454240200922111212391/
参考链接:http://msdn.microsoft.com/zh-cn/library/x9fsa0sw.aspx
分类目录
- arch/management (17)
- computer (38)
- java/j2ee (304)
- lnmpa (237)
- mac/iphone/ipad/android (11)
- mysql/oracle/postgresql (126)
- os/software (74)
- other (518)
- python (6)
- redis/memcached/mongo (31)
- sitebuild (143)
随便看看
标签云
程序员 创业 人生箴言 eclipse 快捷键 术语 索引 unix命令 vim wordpress java学习笔记 环境变量 oracle内置函数 index 人生 数据类型 nohup tuxedo mysql学习笔记 MS-DOS命令 servlet spring 职场进阶 职业进阶 服务器选购 服务器选型 apache JPA MongoDB 注解 tomcat 子女教育 jquery maven JVM aix命令 网络营销 java异常 seo 人生规划 关键字 css 网络推广 struts 系统优化 成长 frame iframe bluehost jdbc select 我的信仰 oracle函数 cookie HashMap 站长工具 乱码 ArrayList secureCRT jsp session tail find halt 事务 oracle单记录函数 算法 URL window table javascript操作表单元素 String 字符串处理 健康 http 域名 情感 more google A记录 域名解析 netstat 弹出对话框 弹出窗口 框架集 框架 excel 字符串 javascript函数 showModalDialog nginx number 数组 sql frameset 开源程序 java数组 软件 oracle服务友情链接
收藏链接