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

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

// 该类是可变的。它的数据可以从类外部修改
class Customer
{
// 用于普通get和set的自动实现属性
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; } // 构造函数
public Customer(double purchases, string name, int ID)
{
TotalPurchases = purchases;
Name = name;
CustomerID = ID;
} // 方法
public string GetContactInfo() { return "ContactInfo"; }
public string GetTransactionHistory() { return "History"; } // 其他的方法、事件等
} class Program
{
static void Main()
{
// 初始化一个新对象
Customer cust1 = new Customer(4987.63, "Northwind", ); // 修改属性
cust1.TotalPurchases += 499.99;
}
}

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

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

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

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

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

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

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

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

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

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

 // 这个类是不可变的。创建对象后,不能从类外部修改它。它使用构造函数初始化其属性。
class Contact
{
// 公共只读属性
public string Name { get; }
public string Address { get; private set; } // 公共构造函数
public Contact(string contactName, string contactAddress)
{
Name = contactName;
Address = contactAddress;
}
} // 这个类是不可变的。创建对象后,不能从类外部修改它。它使用静态方法和私有构造函数初始化其属性。
public class Contact2
{
// 公共只读属性
public string Name { get; private set; }
public string Address { get; } // 私有构造函数
private Contact2(string contactName, string contactAddress)
{
Name = contactName;
Address = contactAddress;
} // 共有工厂方法
public static Contact2 CreateContact(string name, string address)
{
return new Contact2(name, address);
}
} public class Program
{
static void Main()
{
string[] names = {"Terry Adams","Fadi Fakhouri", "Hanying Feng",
"Cesar Garcia", "Debra Garcia"};
string[] addresses = {"123 Main St.", "345 Cypress Ave.", "678 1st Ave",
"12 108th St.", "89 E. 42nd St."}; // 在 select 子句中演示对象创建的简单查询。使用构造函数创建contact对象。
var query1 = from i in Enumerable.Range(, )
select new Contact(names[i], addresses[i]); // 列表元素不能由客户端代码修改。
var list = query1.ToList();
foreach (var contact in list)
{
Console.WriteLine("{0}, {1}", contact.Name, contact.Address);
} // 使用静态工厂方法创建contact2对象。
var query2 = from i in Enumerable.Range(, )
select Contact2.CreateContact(names[i], addresses[i]); // 控制台输出与query1相同。
var list2 = query2.ToList(); // 列表元素不能由客户端代码修改。
// CS0272:
// list2[0].Name = "Eugene Zabokritski"; // 在调试模式下保持控制台打开。
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
} /* 输出:
Terry Adams, 123 Main St.
Fadi Fakhouri, 345 Cypress Ave.
Hanying Feng, 678 1st Ave
Cesar Garcia, 12 108th St.
Debra Garcia, 89 E. 42nd St.
*/

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

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. QToolBar也是QWidget,可以放在QWidget的中间

    可以试着把左边做成一个widget.从上到下依次为:QTextEditQToolBarQTextEdit然后再对她们进行垂直布局(布局是具体需求而定).代码大致如下: TCenterWidget::T ...

  2. 如何在 Xcode 中进行 Qt 开发(可使用使用 Homebrew 来安装qt)

    第一步 安装 Qt 分为两种情况: 1. 希望使用 Qt Quick 等先进Qt5技术, 2. 只需要 Qt 4.8的类库即可. 第一种, 直接去官网下载 Mac安装包, 在此不作过多说明, 开发时也 ...

  3. Realm_King 之 .NET操作XML完整类

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Xml;u ...

  4. 为什么Python中“2==2>1”结果为True

    在Python中,你可能会发现这样一个奇怪的现象: >>> 2 == 2 > 1 True >>> (2 == 2) > 1 False >> ...

  5. 从 docker 到 runC

    笔者在前文<RunC 简介>和<Containerd 简介>中分别介绍了 runC 和 containerd.本文我们将结合 docker 中的其它组件探索 docker 是如 ...

  6. 设置windows服务依赖项

    场景还原:python2.7开发的项目,制作成了windows服务,随系统启动.系统重启后发现服务未能自动启动,检查事件查看器日志发现服务先于Mysql数据库服务启动,由于服务中必须对MySQL进行访 ...

  7. LCN自动补偿

    LCN自动补偿 1当出现需要补偿的数据的时候,LCN将请求tm.compensate.notifyUrl配置的通知地址, 请求补偿的样例数据格式: {"groupId":" ...

  8. selenium2 python 自动化测试实战

    自动化测试,一个现在被炒的火热的词:各大公司都在嚷嚷着要上自动化测试的项目,都在招聘各种自动化测试人员…非常荣幸的受作者邀请来帮忙写这个序,诚惶诚恐,何德何能?不记得何时开始认识的作者了.当初只是作为 ...

  9. select下拉箭头样式重置

    select{ appearance:none; -moz-appearance:none; -webkit-appearance:none; background: url("../ima ...

  10. Python解释器安装教程以及环境变量配置

    Python3.6安装 打开官网:http://www.python.org,下载python3.6.如下图: 下载完成后进行安装.如下图: 验证环境是否配置成功 打开cmd,输入python,按回车 ...