在 C# 3.0 及更高版本,当属性访问器中不需要任何其他逻辑时,自动实现的属性会使属性声明更加简洁。 它们还允许客户端代码创建对象。 当你声明以下示例中所示的属性时,编译器将创建仅可以通过该属性的 get 和 set 访问器访问的专用、匿名支持字段。

下列示例演示一个简单的类,它具有某些自动实现的属性:

  1. // 该类是可变的。它的数据可以从类外部修改
  2. class Customer
  3. {
  4. // 用于普通get和set的自动实现属性
  5. public double TotalPurchases { get; set; }
  6. public string Name { get; set; }
  7. public int CustomerID { get; set; }
  8.  
  9. // 构造函数
  10. public Customer(double purchases, string name, int ID)
  11. {
  12. TotalPurchases = purchases;
  13. Name = name;
  14. CustomerID = ID;
  15. }
  16.  
  17. // 方法
  18. public string GetContactInfo() { return "ContactInfo"; }
  19. public string GetTransactionHistory() { return "History"; }
  20.  
  21. // 其他的方法、事件等
  22. }
  23.  
  24. class Program
  25. {
  26. static void Main()
  27. {
  28. // 初始化一个新对象
  29. Customer cust1 = new Customer(4987.63, "Northwind", );
  30.  
  31. // 修改属性
  32. cust1.TotalPurchases += 499.99;
  33. }
  34. }

在 C# 6 和更高版本中,你可以像字段一样初始化自动实现属性:

  1. public string FirstName { get; set; } = "Jane";

上一示例中所示的类是可变的。 创建客户端代码后可以用于更改对象中的值。 在包含重要行为(方法)以及数据的复杂类中,通常有必要具有公共属性。 但是,对于较小类或仅封装一组值(数据)且只有很少行为或没有行为的结构,则应该通过声明 set 访问器为专用(对使用者的不可变)或通过声明仅一个 get 访问器(除构造函数外都不可变),使对象不可变。

使用自动实现的属性实现轻量类

本示例演示如何创建一个仅用于封装一组自动实现的属性的不可变轻型类。 当你必须使用引用类型语义时,请使用此种构造而不是结构。

可通过两种方法来实现不可变的属性:

  • 可以将 set 访问器声明为专用。 属性只能在该类型中设置,但它对于使用者是不可变的。

    当你声明一个 private set 取值函数时,你无法使用对象初始值设定项来初始化属性。你必须使用构造函数或工厂方法。

  • 也可以仅声明 get 访问器,使属性除了能在该类型的构造函数中可变,在其他任何位置都不可变。

下面的示例演示了实现具有自动实现属性的不可变类的两种方法。 这两种方法均使用 private set 声明其中一个属性,使用单独的 get 声明另一个属性。 第一个类仅使用构造函数来初始化属性,第二个类则使用可调用构造函数的静态工厂方法。

  1. // 这个类是不可变的。创建对象后,不能从类外部修改它。它使用构造函数初始化其属性。
  2. class Contact
  3. {
  4. // 公共只读属性
  5. public string Name { get; }
  6. public string Address { get; private set; }
  7.  
  8. // 公共构造函数
  9. public Contact(string contactName, string contactAddress)
  10. {
  11. Name = contactName;
  12. Address = contactAddress;
  13. }
  14. }
  15.  
  16. // 这个类是不可变的。创建对象后,不能从类外部修改它。它使用静态方法和私有构造函数初始化其属性。
  17. public class Contact2
  18. {
  19. // 公共只读属性
  20. public string Name { get; private set; }
  21. public string Address { get; }
  22.  
  23. // 私有构造函数
  24. private Contact2(string contactName, string contactAddress)
  25. {
  26. Name = contactName;
  27. Address = contactAddress;
  28. }
  29.  
  30. // 共有工厂方法
  31. public static Contact2 CreateContact(string name, string address)
  32. {
  33. return new Contact2(name, address);
  34. }
  35. }
  36.  
  37. public class Program
  38. {
  39. static void Main()
  40. {
  41. string[] names = {"Terry Adams","Fadi Fakhouri", "Hanying Feng",
  42. "Cesar Garcia", "Debra Garcia"};
  43. string[] addresses = {"123 Main St.", "345 Cypress Ave.", "678 1st Ave",
  44. "12 108th St.", "89 E. 42nd St."};
  45.  
  46. // 在 select 子句中演示对象创建的简单查询。使用构造函数创建contact对象。
  47. var query1 = from i in Enumerable.Range(, )
  48. select new Contact(names[i], addresses[i]);
  49.  
  50. // 列表元素不能由客户端代码修改。
  51. var list = query1.ToList();
  52. foreach (var contact in list)
  53. {
  54. Console.WriteLine("{0}, {1}", contact.Name, contact.Address);
  55. }
  56.  
  57. // 使用静态工厂方法创建contact2对象。
  58. var query2 = from i in Enumerable.Range(, )
  59. select Contact2.CreateContact(names[i], addresses[i]);
  60.  
  61. // 控制台输出与query1相同。
  62. var list2 = query2.ToList();
  63.  
  64. // 列表元素不能由客户端代码修改。
  65. // CS0272:
  66. // list2[0].Name = "Eugene Zabokritski";
  67.  
  68. // 在调试模式下保持控制台打开。
  69. Console.WriteLine("Press any key to exit.");
  70. Console.ReadKey();
  71. }
  72. }
  73.  
  74. /* 输出:
  75. Terry Adams, 123 Main St.
  76. Fadi Fakhouri, 345 Cypress Ave.
  77. Hanying Feng, 678 1st Ave
  78. Cesar Garcia, 12 108th St.
  79. Debra Garcia, 89 E. 42nd St.
  80. */

编译器为每个自动实现的属性创建了支持字段。 这些字段无法直接从源代码进行访问。

C#3.0新增功能01 自动实现的属性的更多相关文章

  1. C#2.0新增功能01 分布类与分部方法

    连载目录    [已更新最新开发文章,点击查看详细] 分部类型 拆分一个类.一个结构.一个接口或一个方法的定义到两个或更多的文件中, 每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组 ...

  2. C#5.0新增功能01 异步编程

    连载目录    [已更新最新开发文章,点击查看详细] 如果需要 I/O 绑定(例如从网络请求数据或访问数据库),则需要利用异步编程. 还可以使用 CPU 绑定代码(例如执行成本高昂的计算),对编写异步 ...

  3. C#4.0新增功能01 动态绑定 (dynamic 类型)

    连载目录    [已更新最新开发文章,点击查看详细] C# 4 引入了一个新类型 dynamic. 该类型是一种静态类型,但类型为 dynamic 的对象会跳过静态类型检查. 大多数情况下,该对象就像 ...

  4. C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点

    C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点   第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它 ...

  5. C#2.0新增功能06 协变和逆变

    连载目录    [已更新最新开发文章,点击查看详细] 在 C# 中,协变和逆变能够实现数组类型.委托类型和泛型类型参数的隐式引用转换. 协变保留分配兼容性,逆变则与之相反. 以下代码演示分配兼容性.协 ...

  6. C#基础拾遗系列之二:C#7.0新增功能点

    第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它包括封装.继承和多态性.C#面向对象的行为包括: 统一的类型系统 ...

  7. C#7.0新增功能点

    原文地址:  https://www.cnblogs.com/runningsmallguo/p/8972678.html 第二部分:C#7.0新增的功能 (1)数字字面量的提升: C#7中的数字文字 ...

  8. C#8.0 新增功能

    连载目录    [已更新最新开发文章,点击查看详细] C#8.0提供了许多增强功能 01 Readonly 成员 可将 readonly 修饰符应用于结构的任何成员. 它指示该成员不会修改状态. 这比 ...

  9. C#7.0 新增功能

    连载目录    [已更新最新开发文章,点击查看详细] C# 7.0 向 C# 语言添加了许多新功能 01 out 变量 支持 out 参数的现有语法已在此版本中得到改进. 现在可以在方法调用的参数列表 ...

随机推荐

  1. SimpleDateFormat之后为何多了一年,难道Java API也这么不靠谱?

    这一切的背后到底是机器故障,还是程序的bug? 难道Java API也不靠谱 朋友在我博客上发现一时间明显错误,操作时间怎么会是2016年?在同一个for循环输出到页面的时间,唯独这一个时间不对,整整 ...

  2. Delphi类与方法(几十篇)

    http://www.cnblogs.com/del/category/114896.html

  3. 快速开发平台 WebBuilder 8.4 发布

    WebBuilder是一款强大,全面和高效的应用开发和运行平台.基于浏览器的集成开发环境,可视化和智能化的设计,能轻松完成常规应用和面向手机的移动应用开发.高效.稳定和可扩展的特点,适合复杂企业级应用 ...

  4. 设计模式——(Abstract Factory)抽象工厂“改正为简单工厂”

    设计面向对象软件比较困难,而设计可复用的面向对象软件就更加困难.你必须设计相关类,并设计类的接口和继承之间的关系.设计必须可以解决当前问题,同时必须对将来可能发生的问题和需求也有足够的针对性.掌握面向 ...

  5. 请你讲一讲JavaScript有哪些数据类型, 数据类型判断有哪些方法?

    js的8种数据类型 JavaScript中有8种数据类型, 包括基本数据类型(number, string, boolean, null, undefined, symbol, bigint)和引用数 ...

  6. c#两种方式调用google地球,调用COM API以及调用GEPLUGIN 与js交互,加载kml文件,dae文件。将二维高德地图覆盖到到三维谷歌地球表面。

    网络上资源很多不全面,自己在开发的时候走了不少弯路,在这里整理了最全面的google全套开发,COM交互,web端交互.封装好了各种模块功能. 直接就可以调用. 第一种方式:调用COMAPI实现调用g ...

  7. 【练习题】proj2 字符串压缩

    输入一个字符串,输出简单的压缩 1)单字符串压缩 : 输入:ABBBCCD , 输出AB3C2D 2)多字符串压缩 输入:AABCABCD,输出A(ABC)2D 1)压缩单个字符 #include & ...

  8. spring 5.x 系列第12篇 —— 整合memcached (代码配置方式)

    文章目录 一.说明 1.1 XMemcached客户端说明 1.2 项目结构说明 1.3 依赖说明 二.spring 整合 memcached 2.1 单机配置 2.2 集群配置 2.3 存储基本类型 ...

  9. Codeforces Round #565 (Div. 3) B

    B. Merge it! 题目链接:http://codeforces.com/contest/1176/problem/B 题目 You are given an array a consistin ...

  10. Asp.net HttpClient Proxy(Fiddler)

    <system.net> <defaultProxy> <proxy bypassonlocal="False" usesystemdefault=& ...