C# 属性(一)

Property 是什么意思?

property表示属性,即属固有的特性。比如:

”人“是属,人固有的特性是,姓名、性别、年龄。

“小明”是第一实体, ”人“是第二实体,人是小明这个体的属。小明自然继承”人“属所固有的特性,即小明也具有姓名、性别、年龄特性。对于小明这个个体来说,姓名、性别、年龄是属所具有的特性,而不是小明这个个体本身的特性,因此它们叫属性。这种是相对关系的取名方式。

“小明”要获得属性,就必须通过getter 、和sett方法获得“人”的特性(如何 :姓名、性别、年龄特性)。

Attribute表示特性,即某个实体所独自拥有的特性。

 

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

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

//例如Name属性
//属性定义:
public string Name { get; set; }

//本质
 string Name()
{
    get_Name();
    set_Name(Name);
}
//例如Id属性
private int id;// id是用来保存数据的,也可以将数据保存其他变量上,在wpf的依赖属性中,数据被保存依赖属性对象的变量中,而不保存与本地对象的变量中
public int Id { get => id; set => id = value; }//属性主体表达式

//本质
 string Id()
{
    get_Id();
    set_Id(Name);
}
set_Id(value){id=value;}
get_Id(){return id};

 


 

 

 

 

 

更多内容查看: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 类中的其他代码对其赋值。

 

 

 

posted @ 2021-09-15 17:48  小林野夫  阅读(812)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/