本章讨论属性,它允许源代码用简化语法来调用方法。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字段在构造器中可写)。如果定义属性,最好同时位它提供getset访问方法。
  • 属性方法可抛出异常,字段不会
  • 属性不能作为outref参数传递给方法
  • 属性可能花较长时间完成,字段访问总是立即完成
  • 连续多次访问,属性方法可能每次返回不同的值,而字段每次都是相同的值

对象和集合初始化器

对象初始化语法:

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#--属性详解的更多相关文章

  1. android:exported 属性详解

    属性详解 标签: android 2015-06-11 17:47 27940人阅读 评论(7) 收藏 举报 分类: Android(95) 项目点滴(25) 昨天在用360扫描应用漏洞时,扫描结果, ...

  2. OutputCache属性详解(一)一Duration、VaryByParam

    目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...

  3. OutputCache属性详解(二)一 Location

    目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...

  4. OutputCache属性详解(三)— VaryByHeader,VaryByCustom

    目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...

  5. OutputCache属性详解(四)— SqlDependency

    目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...

  6. WPF依赖属性详解

    WPF依赖属性详解 WPF 依赖属性 英文译为 Dependency Properties,是WPF引入的一种新类型的属性,在WPF中有着极为广泛的应用,在WPF中对于WPF Dependency P ...

  7. HTML video 视频标签全属性详解

    HTML 5 video 视频标签全属性详解   现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8(如果这玩意儿没出事的话)的(Opera.Mozilla.C ...

  8. Android组件---四大布局的属性详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4372222.html Android常见布局有下面几种: LinearL ...

  9. dede的pagelist标签的listsize数字属性详解(借鉴)

    dede的pagelist标签的listsize数字属性详解.见远seo经常用织梦搭建各种网站,有次发现列表页面的分页显示超过div的界限,也就是溢出了或者说是撑破了.后来经过研究发现是pagelis ...

  10. 轻松学习Linux之Shell文件和目录属性详解

    轻松学习Linux之Shell文件和目录属性详解 轻松学习Linux之理解Sitcky 轻松学习Linux之理解umask 轻松学习Linux之理解SUID&SGUID 本系列多媒体教程已完成 ...

随机推荐

  1. 3d效果的图片轮播

    CSS3的3d变换 CSS3给我们提供了一个新的功能,那就是3d变换.3d变换和2d变换的基本API函数类似,只不过多了些在Z轴上的操作,不难使用. 但是,为了让元素拥有3d变换的功能,我们需要给他的 ...

  2. MVC学习系列9--控制器接收从视图传递过来的参数

    前面学习了,从控制器向视图传递数据,现在学习怎么从视图向控制器传递数据. 通常,我们有两种方式,来处理浏览器的请求,一个是GET方式,一个是POST方式.一般来说,直接通过在浏览器中输入URL话,请求 ...

  3. MVC学习系列8--分页和排序

    分页和排序,应该是软件开发中,需要必知必会的技能了,对于分页,网上很多教程,当然,别人终究是别人的,只有自己理解,会了,并且吸收之后,再用自己的语言,传授出来,这才是硬道理.好了,废话说多了.现在我们 ...

  4. 那些年用过的xUnit.net的简单用法

    0x01 前言 单元测试,总是伴随着我们的开发过程,优劣自行google.当然呢,不排除有些公司是不做单元测试的, 但是呢,学多一点东西用来防身还是可以的. 0x02 简单的Demo 写个两数求和的方 ...

  5. 浅谈 C#委托

    看了<CLR via C#>的17章委托后,为自己做一点浅显的总结,也分享给需要的人. .NET通过委托来提供一种回调函数机制,.NET委托提供了很多功能,例如确保回调方法是类型安全的(C ...

  6. Windows Server 2008 R2 安装 media Service 部分更新没有安装 KB963697

    1.下载安装包 Windows6.1-KB963697-x64.msu 2.安装过程失败,提示未安装更新 我是阿里云的服务器,一直出现下面提示 经过反复研究,确定系统问题,重新恢复了初始系统,再进行安 ...

  7. 批量导出access某表内容到word文档

    一.需求: 需要将表中每一条记录中的某些内容导出在一个word文档中,并将这些文档保存在指定文件夹目录下 二.界面,简单设计如下: 三.添加office相关引用 添加后可在解决方案资源管理器中看到: ...

  8. (转)内置系统账户:Local system/Network service/Local Service 区别

    最近会转载一些 MSSQL 基础相关的文章. 参考文献: http://www.cnblogs.com/xianspace/archive/2009/04/05/1429835.html 前言 今天在 ...

  9. require的总结

    前言 我们来看原生的API吧: http://www.requirejs.org/docs/api.html#config 加载javascript文件 RequireJS采用不同的方法来加载脚本,他 ...

  10. 关于SharePoint 2013的工作流(二)

    摸索完了如何画流程实现功能接下来,就是如何配置和部署了.在添加工作流之前,肯定需要一个审批人的配置以及阀值等等的配置. 这个的实现基本上和以前的工作流一致.写法却不一样了,模板自带的都是用js实现的. ...