C# 中的属性是特殊的方法,该方法只负责对私有字段经行的操作,。我们用反编译查看时候看到真实属性是带()的方法,里面还包含get()和set()方法。

属性完成对私有字段的封装。对类的外部用户来说,属性相当一个字段,对类的编写者来说属性就是代码块。真实属性是个无参函数,因此,不能将属性作为 ref 或 out 参数传递。

例如Name属性包含了get_Name()、set_Name()两个方法。

更多内容查看:https://www.cnblogs.com/JerryMouseLi/p/13855733.html

属性的用途:

1、它们可以先验证数据,再允许进行更改;

2、可以在类上透明地公开数据,其中数据实际是从某个其他源(如数据库)检索到的;

3、可以在数据发生更改时采取措施,例如引发事件或更改其他字段的值。

属性的访问器

属性的访问器有3个:get set init

set 访问器

set 访问器类似于返回类型为 void 的方法。 它使用名为 value 的隐式参数,该参数的类型为属性的类型。 在下面的示例中,将 set 访问器添加到 Name 属性

在对象初始化之后才可以使用

init 访问器

C#9.0增加的新功能

在对象初始完成之前可以使用,给字段赋值。
init访问器的功能:

1、让只读字段也可以在 对象初始值设定项中初始化,以前struct只读字段只能在构造函数中初始化。现在可以写在init访问器中了,然后通过对象初始值设定项初始化只读字段。

2、扩展了初始值设定项的功能,从而降低了类或结构中构造函数的数量,在init访问器出来之前struct中的 只读字段只能在构造函数中初始化,这样就要编写不同参数的构造参数。

用于创建 init 访问器的代码与用于创建 set 访问器的代码相同,只不过前者使用的关键字是 init 而不是 set。 不同之处在于,init 访问器只能在构造函数中使用,或通过对象初始值设定项使用。

可以在init属性访问器中修改Readonly 字段

因为 init 访问器只能在初始化期间调用,所以允许它们更改封闭类的只读(readonly)字段,就像在构造函数中一样。

所以可以在init属性访问器中修改 只读(readonly)字段 如下:

public class Person
{
private readonly string firstName;
private readonly string lastName; public string FirstName
{
get => firstName;
init => firstName = (value ?? throw new ArgumentNullException(nameof(FirstName)));
}
public string LastName
{
get => lastName;
init => lastName = (value ?? throw new ArgumentNullException(nameof(LastName)));
}
}

让只读结构体也可以使用对象初始值设定项,让只读字段在init访问器初始化。

 static void Main(string[] args)
{
Test test = new Test() {Name="dfdf",Age=12 };
}
readonly struct Test
{
private static string se;
private static string md;
public string Name {
get {
return se;
}
init
{
se = value;
md = value+"2" ;
}
}
public int Age { get; init; }
}

init访问可以作为字段修饰符

这将允许在类型、派生类型或对象初始值设定项完成构造之前,对字段进行赋值。

class Student
{
public init string FirstName;
public init string LastName;
}
var s = new Student()
{
FirstName = "Jarde",
LastName = "Parsons",
}
s.FirstName = "Jared"; // Error FirstName is readonly

 

init 作 为类 型修 饰 符,类似于readonly,被init修饰的class、struct 的类型中的所有字段自动标记为init

被readonly修饰的所有成员都将都只读的。而被init修饰的 class、struct  的类型中只有字段成员是init

这意味着以下两个类型声明是等效的:

struct Point
{
public init int X;
public init int Y;
}
// vs.
init struct Point
{
public int X;
public int Y;
}

get 访问器

get 访问器的正文类似于方法。 它必须返回属性类型的值。 执行 get 访问器等效于读取字段的值

属性的声明

//1、最原始的属性声明
public string Code
{
get
{
return code;
}
set
{
code = value;
}
}
//2、C#6.0 自动实现的属性
public string Name { get; set; }
public int Age { get; set; } //C#7.0引入表达式主体的属性声明
public string Name { get=>name; set=>name=value; }//value是系统自带的关键字,用来个接收外部的赋值。
private age=1;
public int Age => age; //只读Age 属性以表达式主体定义的形式实现
 

自动实现的属性

 public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerId { get; set; }

属性的初始化

1\构造函数初始化


Cat sameCat = new Cat("Fluffy",10);

2\初始值设定项

只读属性无法使用对象初始值设定项,init 可以代替set 为初始值设定项准备的,设置后不能再修改了。

Cat cat = new Cat { Age = 10, Name = "Fluffy" };
Cat sameCat = new Cat("Fluffy"){ Age = 10 };
 
 

属性赋值

public string FirstName { get;} = "Jane";
public string FirstName { get; set; } = "Jane"; //在 C# 6 和更高版本中,你可以像字段一样初始化自动实现属性

抽象类属性

抽象类可拥有抽象属性,这些属性应在派生类中被实现

abstract class Shape
{
public abstract double Area
{
get;
set;
}
} class Square : Shape
{
public double side; //constructor
public Square(double s) => side = s; public override double Area
{
get => side * side;
set => side = System.Math.Sqrt(value);
}
}

接口属性

接口属性通常没有主体,访问器指示属性是读写、只读还是只写。从 C# 8.0 开始,接口可为成员(包括属性)定义默认实现。这样这个可不是自动化实现属性,因为接口属性不会生成 private string name;

public interface ISampleInterface
{
// Property declaration:
string Name
{
get;
set;
}
}

可以在继承接口的类中使用属性的完全限定名称,它引用其中声明成员的接口。 例如:

interface IEmployee
{
string Name
{
get;
set;
} } public class Employee : IEmployee
{
string IEmployee.Name
{
get { return "Employee Name"; }
set { }
}
}

属性表达式

格式:PropertyType PropertyName => expression; 因为没有set访问器,所以直接省掉get。
public class Location
{
private string locationName;
public string Name => locationName;
}

和下面写法一样

public class Location
{
private string locationName;
public string Name
{
get => locationName;
}
}

只读属性

public class Person
{
public string FirstName { get; private set; } // remaining implementation removed from listing
}

现在,可以从任意代码访问 FirstName 属性,但只能从 Person 类中的其他代码对其赋值。

 

C# 属性(一)的更多相关文章

  1. jqu

    1 /*2 * 说明:3 * 本源代码的中文注释乃Auscarlin呕心沥血所作.旨在促进jQuery的传播以及向广大jQuery爱好者提供一个进阶4 *的途径,以让各位更加深入地了解jQuery,学 ...

  2. js-静态、原型、实例属性

    本篇来说一下js中的属性: 1.静态属性 2.原型属性 3.实例属性 静态属性: function klass(){} var obj=new klass(); klass.count=0; klas ...

  3. 探究@property申明对象属性时copy与strong的区别

    一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ...

  4. CSS HTML元素布局及Display属性

    本篇文章主要介绍HTML的内联元素.块级元素的分类与布局,以及dispaly属性对布局的影响. 目录 1. HTML 元素分类:介绍内联元素.块级元素的分类. 2. HTML 元素布局:介绍内联元素. ...

  5. CSS float 浮动属性

    本篇主要介绍float属性:定义元素朝哪个方向浮动. 目录: 1. 页面布局方式:介绍文档流.浮动层以及float属性. 2. float:left :介绍float为 left 时的布局方式. 3. ...

  6. CSS Position 定位属性

    本篇文章主要介绍元素的Position属性,此属性可以设置元素在页面的定位方式. 目录 1. 介绍 position:介绍position的值以及辅助属性. 2. position 定位方式:介绍po ...

  7. npm package.json属性详解

    概述 本文档是自己看官方文档的理解+翻译,内容是package.json配置里边的属性含义.package.json必须是一个严格的json文件,而不仅仅是js里边的一个对象.其中很多属性可以通过np ...

  8. JavaScript特性(attribute)、属性(property)和样式(style)

    最近在研读一本巨著<JavaScript忍者秘籍>,里面有一篇文章提到了这3个概念. 书中的源码可以在此下载.我将源码放到了线上,如果不想下载,可以直接访问在线网址,修改页面名就能访问到相 ...

  9. 【用户交互】APP没有退出前台但改变系统属性如何实时更新UI?监听系统广播,让用户交互更舒心~

    前日,一小伙伴问我一个问题,说它解决了半天都没解决这个问题,截图如下: 大概楼主理解如下: 如果在应用中有一个判断wifi的开关和一个当前音量大小的seekbar以及一个获取当前电量多少的按钮,想知道 ...

  10. jQuery的属性

    The Write Less , Do More ! jQuery的属性 1. attr(name|properties|key,value|fn) : 设置或返回被选元素的属性值 ①获取属性 < ...

随机推荐

  1. JVM诊断及工具笔记(2)使用arthas定位哪里执行了System#gc()

    笔者是汽车之家实时计算平台的一名小伙伴.负责flink平台,数据湖及kafka平台的设计与开发.平时擅长做平台设计,定位及解决各种疑难杂症.第二篇文章,讲的点依旧很小,但是这次图多!!! 在这里感谢支 ...

  2. Vue 之 vue-cropper 组件实现头像裁剪功能

    组件与api地址: npm地址地址:https://www.npmjs.com/package/vue-cropper/v/0.4.7 GitHub地址:https://github.com/xyxi ...

  3. springboot 修改关闭banner的方法

    一.修改banner. 1.1 替换banner: 需要在resources(classpath)目录中创建文件 banner.txt 1.2 上图   banner.txt 里面可以使用文字,也可以 ...

  4. plsql 触发器介绍 语句级别触发器、行级别触发器。

    /* 分类: 1.DDL触发器 执行create,alter,drop操作时,会激活的触发器 2.DML触发器 执行增.删除.修改时,激活的触发器 3.系统事件触发器 执行特定的系统事件时(启动.加载 ...

  5. MyBatis加强(1)~myBatis对象关系映射(多对一关系、一对多关系)、延迟/懒加载

    一.myBatis对象关系映射(多对一关系.一对多关系) 1.多对一关系: ---例子:多个员工同属于一个部门. (1)myBatis发送 额外SQL: ■ 案例:员工表通过 dept_id 关联 部 ...

  6. C++学习Day 1

    c++的函数需要声明才能再写他的定义,声明可以写多次,如果执行在main之前可以不写,全写不会犯错,现在看好像c++的函数定义里没有out,也没有变量的public和private(后面有再改) 声明 ...

  7. X000010

    P1829 [国家集训队]Crash的数字表格 / JZPTAB 题意:求 \({\rm S}(n,m)=\sum\limits_{i=1}^n\sum\limits_{j=1}^m{\rm lcm} ...

  8. STL priority_queue 优先队列 小记

    今天做题发现一个很有趣的地方,竟然还是头一次发现,唉,还是太菜了. 做图论用STL里的priority_queue去优化prim,由于特殊需求,我需要记录生成树中是用的哪些边. 于是,我定义的优先队列 ...

  9. ForkJoinPool简单使用

    简介 ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个"小任务",把多个"小任务"放到多个处理器核心上并行执行, ...

  10. 通过ANT生成MANIFEST.MF中的Class-Path属性

    原文地址:http://reason2003.iteye.com/blog/1627353 之前做一个项目,主程序打包成一个jar文件,因为用到了很多第三方的lib包,所以直接通过java命令运行ja ...