本章讨论属性,它允许源代码用简化语法来调用方法。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#--属性详解的更多相关文章

  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. react初始(2)

    既然我开始了react的学习,就没有停下来的理由了,我应该很幸运我还有这个时间去学习react,我不认为我聪明,但是我认为我够努力.我先在或许是一个不知道未来该是怎样的人,我们的迷茫和无知源于你不去接 ...

  2. TeamCity : 安装 Server

    本文介绍在 Ubuntu Server 14.04 中安装 TeamCity Server 10.0.1.Ubuntu Server 上已经创建了用户  tcuser.TeamCity 的安装包为 T ...

  3. AngularJS中的JSONP实践

    欢迎大家指导与讨论: ) 概念 首先呢,Json和JSONP是不一样的哦.Json呢,是众多数据存储的其中一种格式,是数据书写方式的其中一种.好比是大中华众多诗体的一种(比如说是七言诗吧).这种诗体规 ...

  4. Xamarin.Android之Spinner的简单探讨

    一.前言 今天用了一下Spinner这个控件,主要是结合官网的例子来用的,不过官网的是把数据写在Strings.xml中的, 某种程度上,不是很符合我们需要的,比较多的应该都是从数据库读出来,绑定上去 ...

  5. Microsoft Visual Studio 2008 未能正确加载包“Visual Web Developer HTML Source Editor Package” | “Visual Studio HTM Editor Package”

    在安装Microsoft Visual Studio 2008 后,如果Visual Studio 2008的语言版本与系统不一致时,比如:在Windows 7 English System 安装Vi ...

  6. @Html.Raw显示一张图片

    在ASP.NET MVC中,显示一张图片,是很方便的事情,完全可以在控制器中组合html代码,并传给视图. 下面一个简单的例子: public ActionResult HtmlRawImage() ...

  7. C#集合--Dictionary

    字典(dictionary)是一个集合,其中每个元素都是一个键/值对.字典(Dictionaries)是常用于查找和排序的列表. .NET Framework通过IDictionary接口和IDict ...

  8. 谈一谈SQL Server中的执行计划缓存(上)

    简介 我们平时所写的SQL语句本质只是获取数据的逻辑,而不是获取数据的物理路径.当我们写的SQL语句传到SQL Server的时候,查询分析器会将语句依次进行解析(Parse).绑定(Bind).查询 ...

  9. MySQL 5.7:非结构化数据存储的新选择

    本文转载自:http://www.innomysql.net/article/23959.html (只作转载, 不代表本站和博主同意文中观点或证实文中信息) 工作10余年,没有一个版本能像MySQL ...

  10. 为什么你不应该使用 MongoDB

    本文转载自: http://www.oschina.net/translate/why-you-should-never-use-mongodb (只作转载, 不代表本站和博主同意文中观点或证实文中信 ...