C#--属性详解
本章讨论属性,它允许源代码用简化语法来调用方法。CLR支持两种属性:无参属性 有参属性。在C#中称有参属性为索引器
无参属性
面向对象设计和编程的重要原则之一就是数据封装,意味着类型的字段永远不应该公开,否则很容易因为不恰当的使用字段而破坏对象的状态。
下面这种使用方式是不好的:
public sealed class Employee{
public String Name;
public Int32 Age
}
Employee e = new Employee();
e.Name = "Jeffrey Richter";
e.Age = 45;
//下面这种方式很容易就破坏了对象的状态
e.Age = -5;
基于以上原因,强烈建议将所有字段都设为private.要允许用户或类型获取或设置状态信息就公开一个针对该用途的方法。封装了字段访问的方法通常称为访问器方法。
比如下面这样使用属性:
private sealed class Employee {
private String m_Name; // prepended 'm_' to avoid conflict
private Int32 m_Age; // prepended 'm_' to avoid conflict
public String Name {
get { return (m_Name); }
set { m_Name = value; } // 'value' identifies new value
}
public Int32 Age {
get { return (m_Age); }
set {
if (value <= 0) // 'value' identifies new value
throw new ArgumentOutOfRangeException("value", "must be >0");
m_Age = value;
}
}
}
emp.Name = "Jeffrey Richter";
emp.Age = 45; // Updates the age
Console.WriteLine("Employee info: Name = {0}, Age = {1}", emp.Name, emp.Age);
e.Age = -5; // 会抛出`ArgumentOutOfRangeException`异常
Int32 EmployeeAge = e.Age ;
注意:我相信大部分的初学者在开始之初都讲不出字段和属性的区别,现在我可以稍微尝试着说下了。字段经常用来封装一些不经常修改的内容,建议将字段设为private,而属性一定要将取值get和设值set想象成两个方法,虽然C#简化了这种语法,但编译器在后台仍然会在指定的属性名之前添加set_和get_前缀来生成方法名,更适合用来封装那些可能发生变化的内容。可以将属性看成智能字段,可以设置只读属性或只写属性。
自动实现的属性
public String Name {get;set;}
声明属性而不提供get/set方法的实现,C#会自动为你声明一个私有字段。实现get/set方法。
合理定义属性
- 属性可以只读或只写,字段访问总是可读或可写的(
readonly字段在构造器中可写)。如果定义属性,最好同时位它提供get和set访问方法。 - 属性方法可抛出异常,字段不会
- 属性不能作为
out或ref参数传递给方法 - 属性可能花较长时间完成,字段访问总是立即完成
- 连续多次访问,属性方法可能每次返回不同的值,而字段每次都是相同的值
对象和集合初始化器
对象初始化语法:
Employee e = new Employee(){ Name = "Jeff" , Age = 45 };
如果想调用的本来就是一个无参构造器,C#还允许省略括号
下面演示集合初始化器,下面构造一个ClassRoom对象,并初始化Students集合
Classroom classroom = new Classroom{
Student = { "Jeff" , "Kristin" , "Aidan"}
};
使用起来还是非常方便的,编译器在后台默认调用集合的Add方法,把对象添加到集合中。
匿名类型
利用C#的匿名类型功能,可以很简洁的语法来自动声明不可变的元组类型。
var o1 = new { Name = "Jeff", Year = 1964 };
// Display the properties on the console:
Console.WriteLine("Name={0}, Year={1}", o1.Name, o1.Year);
匿名类型经常与LINQ联合使用
有参属性
在C#中有参属性被称为索引器。C#是用数组风格的语法来公开有参属性,换句话说索引器可以看成是C#对[]操作符的重载
下面演示一个BitArray类,它允许哦那个数组风格的语法来索引一组二进制位
internal sealed class BitArray {
//容纳了一个二进制位的私有字节数组
// Private array of bytes that hold the bits
private Byte[] m_byteArray;
private Int32 m_numBits;
// Constructor that allocates the byte array and sets all bits to 0
//分配字节数组,并将所有为初始为0
public BitArray(Int32 numBits) {
// Validate arguments first.
if (numBits <= 0)
throw new ArgumentOutOfRangeException("numBits must be > 0");
// Save the number of bits.
m_numBits = numBits;
// Allocate the bytes for the bit array.
m_byteArray = new Byte[(m_numBits + 7) / 8];
}
// This is the indexer.
// 这是索引器
public Boolean this[Int32 bitPos] {
// 这是索引器的get方法
get {
// Validate arguments first
if ((bitPos < 0) || (bitPos >= m_numBits))
throw new ArgumentOutOfRangeException("bitPos", "bitPos must be between 0 and " + m_numBits);
// Return the state of the indexed bit.
return ((m_byteArray[bitPos / 8] & (1 << (bitPos % 8))) != 0);
}
// 索引器的set访问器方法
set {
if ((bitPos < 0) || (bitPos >= m_numBits))
throw new ArgumentOutOfRangeException("bitPos", "bitPos must be between 0 and " + m_numBits);
if (value) {
// Turn the indexed bit on.
m_byteArray[bitPos / 8] = (Byte)
(m_byteArray[bitPos / 8] | (1 << (bitPos % 8)));
} else {
// Turn the indexed bit off.
m_byteArray[bitPos / 8] = (Byte)
(m_byteArray[bitPos / 8] & ~(1 << (bitPos % 8)));
}
}
}
}
private static void BitArrayTest() {
// Allocate a BitArray that can hold 14 bits.
// 构造一个数组
BitArray ba = new BitArray(14);
// Turn all the even-numbered bits on by calling the set accessor.
for (Int32 x = 0; x < 14; x++) {
//这里实际是调用的set方法,将偶数为设为true
ba[x] = (x % 2 == 0);
}
// Show the state of all the bits by calling the get accessor.
for (Int32 x = 0; x < 14; x++) {
// 这里调用了get方法,显示状态。
Console.WriteLine("Bit " + x + " is " + (ba[x] ? "On" : "Off"));
}
}
C#使用this[...]作为表达索引器的语法,如上面的
public Boolean this[Int32 bitpos]
代表set时,传入一个index的索引,get时返回一个Boolean类型
总结
今天的内容还是比较有趣的, 搞懂了一直以来困惑的字段和属性的区别。复习了对象初始化器、集合初始化器、匿名类型等等,最后学习了下有参属性即索引器。以前在做题的时候遇到过,现在也清楚多了。接下来到了事件了哈哈,做个小栗子一起学习下吧。
C#--属性详解的更多相关文章
- android:exported 属性详解
属性详解 标签: android 2015-06-11 17:47 27940人阅读 评论(7) 收藏 举报 分类: Android(95) 项目点滴(25) 昨天在用360扫描应用漏洞时,扫描结果, ...
- OutputCache属性详解(一)一Duration、VaryByParam
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...
- OutputCache属性详解(二)一 Location
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...
- OutputCache属性详解(三)— VaryByHeader,VaryByCustom
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...
- OutputCache属性详解(四)— SqlDependency
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...
- WPF依赖属性详解
WPF依赖属性详解 WPF 依赖属性 英文译为 Dependency Properties,是WPF引入的一种新类型的属性,在WPF中有着极为广泛的应用,在WPF中对于WPF Dependency P ...
- HTML video 视频标签全属性详解
HTML 5 video 视频标签全属性详解 现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8(如果这玩意儿没出事的话)的(Opera.Mozilla.C ...
- Android组件---四大布局的属性详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4372222.html Android常见布局有下面几种: LinearL ...
- dede的pagelist标签的listsize数字属性详解(借鉴)
dede的pagelist标签的listsize数字属性详解.见远seo经常用织梦搭建各种网站,有次发现列表页面的分页显示超过div的界限,也就是溢出了或者说是撑破了.后来经过研究发现是pagelis ...
- 轻松学习Linux之Shell文件和目录属性详解
轻松学习Linux之Shell文件和目录属性详解 轻松学习Linux之理解Sitcky 轻松学习Linux之理解umask 轻松学习Linux之理解SUID&SGUID 本系列多媒体教程已完成 ...
随机推荐
- 【Java心得总结五】Java容器上——容器初探
在数学中我们有集合的概念,所谓的一个集合,就是将数个对象归类而分成为一个或数个形态各异的大小整体. 一般来讲,集合是具有某种特性的事物的整体,或是一些确认对象的汇集.构成集合的事物或对象称作元素或是成 ...
- Kooboo CMS 无聊随笔 (1)
因为公司的框架不开源,但是自己一直都有研究框架的兴趣,所以拿了一个开源的框架过来,而这个开源的框架就是Kooboo CMS.首先我无法用言语来形容我对这个CMS的赞美之词了,总之大家知道一点,这个CM ...
- 在ASP.NET MVC 中获取当前URL、controller、action
一.URL的获取很简单,ASP.NET通用: [1]获取 完整url (协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [2]获取 虚拟 ...
- Compute Resource Consolidation Pattern 计算资源整合模式
Consolidate multiple tasks or operations into a single computational unit. This pattern can increase ...
- 你必须知道ASP.NET知识------关于动态注册httpmodule(对不起汤姆大叔)
一.关于动态注册的问题 很多人看过汤姆大叔的MVC之前的那点事儿系列(6):动态注册HttpModule ,其实汤姆大叔没有发现httpmodule动态注册的根本机制在哪里. 亦即:怎么动态注册?为什 ...
- [转]Teach Yourself Programming in Ten Years——用十年教会自己编程
作者:Peter Norvig 译者:刘海粟 本文原文为:http://norvig.com/21-days.html 该翻译文档的PDF版可以在这里获得:http://download.csdn.n ...
- jQuery弹出深色系层菜单
低调奢华jQuery弹出层菜单,使用新版的jQuery库,兼容多种浏览器.Demo展示: http://hovertree.com/texiao/layer/3/ 本特效可以作为网站的引导页,使用jQ ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- ASP.NET MVC开发中常见异常及解决方案
ASP.NET MVC4入门到精通系列目录汇总 NHibernate:no persister for 异常 1.配置文件后缀名写错 mapping file 必须是.hbm.xml结尾 2.Web. ...
- GetEnumerator();yield
GetEnumerator()方法的实质实现: 说明:只要一个集合点出GetEnumerator方法,就获得了迭代器属性,就可以用MoveNext和Current来实现foreach的效果,如上图. ...