10.1 无参属性

10.1.1 自动实现的属性

10.1.2 合理定义属性

  • 属性可以只读或只写,而字段访问总是可读和可写的(一个例外是 readonly 字段仅在构造器中可写).
  • 属性方法可能抛出异常;字段访问永远不会.
  • 属性不能作为 out 或 ref 参数传给方法,而字段可以.
  • 属性方法可能花较长时间执行,字段访问则总是立即完成.线程同步不要使用属性,而用方法.从MashalByRefObject派生的类永远都不应该使用属性.
  • 连续多次调用,属性方法每次都可能返回不同的值,字段则每次都返回相同的值.
  • 属性方法可能造成明显的副作用(不同的赋值顺序,可能会出现不同的行为),字段访问则永远不会.
  • 属性方法可能需要额外的内存,或者返回的引用并非指向对象状态一部分,造成对返回对象的修改作用不到原始对象身上.

10.1.3 对象和集合初始化器

    String s= new Employee (){ Name="Jeff", Age=45 }.ToString().ToUpper();
//如果想调用的本来就是一个无参构造器,c#还允许省略起始大括号之前的圆括号.
String s= new Employee { Name="Jeff", Age=45 }.ToString().ToUpper();

10.1.4 匿名类型

    var o1=new{ Name="Jeff", Year=1964};
Console.WriteLine("Name={0},Year={1}",o1.Name,o1.Year); //或
String Name="Grant";
DateTime dt= DateTime.Now;
//有两个属性的一个匿名类型
//1.String Name 属性设为"Grant"
//2.Int32 Year 属性设为dt中的年份
var o2 = new { Name, dt.Year };
Console.WriteLine("Name={0},Year={1}",o2.Name,o2.Year);
  • 如果源代码中定义了多个匿名类型,且这些类型具有相同的结构,编译器只会创建一个匿名类型定义,但创建该类型的多个实例.o1=o2
  • 匿名类型的实例不能泄露到方法外部.
  • 方法原型不能接受匿名类型的参数.
  • 方法不能返回匿名类型的引用.

10.1.5 System.Tuple类型

    //Tuple没啥好写的,还是写写dynamic吧
dynamic e = new System.Dynamic.ExpandoObject();
e.x = 6; //添加一个Int32 'x'属性,其值为6
e.y = "Jeff"; //添加一个String 'y'属性,其值为"Jeff"
e.z = null; //添加一个Object 'z'属性,其值为null //查看所有属性及其值:
foreach (var v in (IDictionary<String, Object>)e)
Console.WriteLine("key={0},v={1}", v.Key, v.Value);

10.2 有参属性(c#称为索引器)

    public sealed class BitArray
{
//容纳了二进制位的私有字节数组
private byte[] m_byteArray;
private int m_numBits; //下面的构造器用于分配字节数组,并将所有位设为0
public BitArray(int numBits)
{
//先验证实参
if (numBits <= 0)
throw new ArgumentOutOfRangeException(nameof(numBits)); //保存位的个数
m_numBits = numBits;
//为位数组分配字节
m_byteArray = new byte[(numBits + 7) / 8];
} //下面是索引器(有参属性)
public bool this[int bitPos]
{
//下面是索引器的get访问器方法
get
{
//先验证实参
if ((bitPos < 0) || (bitPos >= m_numBits))
throw new ArgumentOutOfRangeException(nameof(bitPos)); //返回指定索引处的位的状态
return (m_byteArray[bitPos / 8] & (1 << (bitPos % 8))) != 0;
} //下面是索引器的set访问器方法
set
{
if ((bitPos < 0) || (bitPos >= m_numBits))
throw new ArgumentOutOfRangeException(nameof(bitPos), bitPos.ToString()); if (value)
{
//将指定索引处的位设为true
m_byteArray[bitPos / 8] = (byte)(m_byteArray[bitPos / 8] | (1 << (bitPos % 8)));
}
else
{
//将指定索引处的位设为false
m_byteArray[bitPos / 8] = (byte)(m_byteArray[bitPos / 8] & ~(1 << (bitPos % 8)));
}
}
}
}

BitArray类的索引器用起来很简单:

//分配含14个位的BitArray数组
BitArray ba = new BitArray(14); //调用set访问器方法,将编号为偶数的所有位都设为true
for (int x = 0;x < 14; x++){
ba[x]=(x % 2 == 0);
} //调用get访问器方法显示所有位的状态
for (int x = 0; x < 14; x++){
Console.WriteLine("Bit " + x + " is " +(ba[x] ? "On" : "Off"));
}
  • 可以通过IndexerNameAttribute特性改变编译器使用的索引器名称(默认为Item,并在前面加get_或set_前缀).System.String改变索引器名称为 Chars .
  • c#允许一个类型定义多个索引器,只要索引器的参数集不同.
  • 对于支持多个有参属性的编程语言,必须选中一个有参属性,通过DefaultMemberAttribute特性来标识.这是C#代码唯一能访问的有参属性.

10.3 调用属性访问器方法时的性能

  • 对于简单的get和set访问器方法,JIT编译器会将代码内联(inline,或者说嵌入).

10.4 属性访问器的可访问性

// ⑴
public class SomeType{
private string m_name;
public string Name {
get { return m_name; }
// ⑵
protected set { m_name = value; }
}
}
  • ⑴ 必须为属性本身指定限制最小的可访问性
  • ⑵ 两个访问器只能选择一个来使用限制较大的

返回目录

<NET CLR via c# 第4版>笔记 第10章 属性的更多相关文章

  1. <NET CLR via c# 第4版>笔记 第19章 可空值类型

    System.Nullable<T> 是结构. 19.1 C# 对可空值类型的支持 C# 允许用问号表示法来声明可空值类型,如: Int32? x = 5; Int32? y = null ...

  2. <NET CLR via c# 第4版>笔记 第18章 定制特性

    18.1 使用定制特性 FCL 中的几个常用定制特性. DllImport 特性应用于方法,告诉 CLR 该方法的实现位于指定 DLL 的非托管代码中. Serializable 特性应用于类型,告诉 ...

  3. <NET CLR via c# 第4版>笔记 第17章 委托

    17.1 初识委托 .net 通过委托来提供回调函数机制. 委托确保回调方法是类型安全的. 委托允许顺序调用多个方法. 17.2 用委托回调静态方法 将方法绑定到委托时,C# 和 CLR 都允许引用类 ...

  4. <NET CLR via c# 第4版>笔记 第16章 数组

    //创建一个一维数组 int[] myIntegers; //声明一个数组引用 myIntegers = new int[100]; //创建含有100个int的数组 //创建一个二维数组 doubl ...

  5. <NET CLR via c# 第4版>笔记 第13章 接口

    13.1 类和接口继承 13.2 定义接口 C#用 interface 关键字定义接口.接口中可定义方法,事件,无参属性和有参属性(C#的索引器),但不能定义任何构造器方法,也不能定义任何实例字段. ...

  6. <NET CLR via c# 第4版>笔记 第12章 泛型

    泛型优势: 源代码保护 使用泛型算法的开发人员不需要访问算法的源代码.(使用c++模板的泛型技术,算法的源代码必须提供给使用算法的用户) 类型安全 向List<DateTime>实例添加一 ...

  7. <NET CLR via c# 第4版>笔记 第5章 基元类型、引用类型和值类型

    5.1 编程语言的基元类型 c#不管在什么操作系统上运行,int始终映射到System.Int32; long始终映射到System.Int64 可以通过checked/unchecked操作符/语句 ...

  8. <NET CLR via c# 第4版>笔记 第6章 类型和成员基础

    6.1 类型的各种成员 6.2 类型的可见性 public 全部可见 internal 程序集内可见(如忽略,默认为internal) 可通过设定友元程序集,允许其它程序集访问该程序集中的所有inte ...

  9. <NET CLR via c# 第4版>笔记 第7章 常量和字段

    7.1 常量 常量 是值从不变化的符号.定义常量符号时,它的值必须能够在编译时确定. 只能定义编译器识别的基元类型的常量,如果是非基元类型,需把值设为null. 常量的值直接嵌入代码,所以不能获取常量 ...

随机推荐

  1. centos MySQL主从配置 ntsysv chkconfig setup命令 配置MySQL 主从 子shell MySQL备份 kill命令 pid文件 discuz!论坛数据库读写分离 双主搭建 mysql.history 第二十九节课

    centos  MySQL主从配置 ntsysv   chkconfig  setup命令  配置MySQL 主从 子shell  MySQL备份  kill命令  pid文件  discuz!论坛数 ...

  2. 103-advanced-上下文

    上下文提供了一种通过组件树传递数据的方法,无需在每个级别手动传递道具. 在典型的React应用程序中,数据通过prop自上而下(父到子)传递,但对于应用程序中许多组件所需的某些类型的道具(例如场所偏好 ...

  3. Windows 10 升级软件 Windows 10 易升

    进入 https://www.microsoft.com/zh-cn/software-download/windows10 点立即更新,弹出如下下载地址. https://download.micr ...

  4. loadrunner11的移动端性能测试之结果分析

    测试步骤之结果分析器(Analysis) 进入Analysis 当场景停止运行后,可从Controller中进入.点击[Results]—[Analysis Results]见下图: 若想打开一个已保 ...

  5. python16_day35【算法】

    一.BTree class BinTreeNode: def __init__(self, data): self.data = data self.lchild = None self.rchild ...

  6. 前端基础(JavaScript)

    JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.( ...

  7. mysql锁机制之综述(一)

    https://zhuanlan.zhihu.com/p/29150809 一.数据库有锁机制的原因. 数据库锁定机制简单来说,就是数据库为了保证数据的一致性和有效性,而使各种共享资源在被并发访问变得 ...

  8. 2018-2019 ICPC, NEERC, Northern Eurasia Finals (Unrated, Online Mirror, ICPC Rules, Teams Preferred) Solution

    A. Alice the Fan Solved. 题意: 两个人打网球,要求teamA 的得分与其他队伍拉开尽量大 输出合法的方案 思路: $dp[i][j][k][l] 表示 A 赢i局,其他队伍赢 ...

  9. uva1401 dp+Trie

    这题说的是给了一个长的字符串长度最大300000,又给了4000个单词 单词的长度不超过100.计算这个字符串能组成多少种不同单词的组合,求出方案总数.dp[i]以第i个字符为开始的字符串能有多少种的 ...

  10. selenium-python读取XML文件

    首先这是我们要读取的XML文件 <?xml version="1.0" encoding="utf-8" ?><info> <ba ...