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 本系列多媒体教程已完成 ...
随机推荐
- ZOJ Problem Set - 1334 Basically Speaking ac代码及总结
这道题目不难,是一道简单的进制转换问题,但是发现了自己两个遗漏的知识点: 1.关于scanf (1)scanf函数在输入时是以回车或者空格作为一次输入的结束 (2)scanf函数在输入字符串的过程中是 ...
- 关于C#静态变量初始化问题
关于这个静态变量,平时自己没有太认真的去认识.最近调项目的bug,让我重新认识了静态变量的特点. 其实,我们一直都在说:静态变量只在类第一次初始化的时候进行初始化,以后都不初始化. 很简单的一句话,但 ...
- 程序集与反射技术(C#)
首先我们来看程序集,程序集是代码进行编译是的一个逻辑单元,把相关的代码和类型进行组合,然后生成PE文件(例如可执行文件.exe和类库文件.dll).由于程序集在编译后并不一定会生成单个文件,而可能会生 ...
- AssetsManagerEx 组件使用说明
原因 在网络上找了一圈也没有找到一个像样的说明.如果不是我们技术组的大大说这个东西可以用我都快放弃了. 稍微阅读了一下这个组件的源代码.发现该有的功能都有(如下所列). 其实最初吸引我们用这个东西的功 ...
- python处理空格脚本
博客园上传代码时拷贝vs里面的代码不能直接粘贴,否则空格会不符合要求 去掉空格代码 # -*- coding: utf-8 -*- '''打开delSpace.txt文本并删除每行开头的八个空格''' ...
- Visual Studio中安装viemu后,vim vax 快捷键大全
高效率移动 在插入模式之外 基本上来说,你应该尽可能少的呆在插入模式里面,因为在插入模式里面VIM就像一个“哑巴”编辑器一样.很多新手都会一直呆在插入模式里面,因为这样易于使用.但VIM的强大之处在于 ...
- 转载:《TypeScript 中文入门教程》 6、命名空间
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变 ...
- ABP使用及框架解析系列 - [Unit of Work part.1-概念及使用]
前言 ABP ABP是“ASP.NET Boilerplate Project”的简称. ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上的开 ...
- ASP.NET MVC搭建项目后台UI框架—3、面板折叠和展开
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- 网站banner无缝轮播
网站banner无缝轮播 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...