属性Property不是变量。 它们是由名为访问器方法来实现的一种方法。
实例属性表示的是实例的某个数据,通过这个数据反映实例当前的状态
静态属性表示的是类型的某个数据,通过这个数据反映类型当前的状态
意义:
防止恶意赋值(通过属性间接访问字段,对字段的一种保护),通过在Get和Set访问器函数中增加一些限制,对赋值进行合法检验防止污染字段。
语法(糖):
自动实现的属性
如果在访问器中没有任何附加逻辑可写成语法糖的样式。与一个共有字段没区别,不受保护,一般用在传递数据的类(即不需要取改的类,只传递)
属性进化史
未对字段进行保护添加属性保护字段
由于赋值和取值的两个方法很冗余不如直接给变量赋值的清晰,因此MS创造了“属性”一概念
简洁多了,赋值从stu1.SetAge(10)变成stu.Age = 10;取值从stu1.GetAge()变成stu1.Age
属性的初始化
隐藏字段
如果没有显式声明属性对应的字段,直接声明属性,编译器会自动生成的隐藏字段
访问控制
PS:同一类内的属性之间,无论什么修饰符,都可以互相访问到。
属性可以是读-写属性(既有 get
访问器又有 set
访问器)
只读属性(有 get
访问器,但没有 set
访问器)只读是针对类外的,类外因为字段被private的modifier修饰,因此只能通过属性访问字段,而类内不受private影响可以不通过属性访问字段
或只写访问器(有 set
访问器,但没有 get
访问器)。 只写属性很少见
set
访问器有两个特殊的访问修饰符:
set
访问器可以将init
作为其访问修饰符。 只能从对象初始值设定项或类型的构造函数调用该set
访问器。 它比set
访问器上的private
更严格。- 自动实现的属性可以在不使用访问器的情况下
set
声明get
访问器。 在这种情况下,编译器只允许从类型的构造函数调用set
访问器。 它比set
访问器上的init
访问器更严格。
不写set和将set用private修饰是不同的效果:
1.不写set:无论类内外给属性赋值,报错只读属性不能被赋值。类内也依然可以改变其值,因为不受private影响而绕开属性,直接给字段赋值即可
2.写set但用private修饰:如果从声明这个字段的类外访问会报错:set访问器不可访问。setter不能从类外部访问,只能从类内部访问,可通过类内对Age进行赋值
抽象属性(Abstract Properties)
抽象类可拥有抽象属性,这些属性应在派生类中被实现。下面的程序说明了这点:
using System;
namespace Runoob
{
public abstract class Person
{
public abstract string Name { get; set; }
public abstract int Age { get; set; }
}
class Student : Person
{
// 声明自动实现的属性
public string Code { get; set; } = "N.A";
public override string Name { get; set; } = "N.A";
public override int Age { get; set; } = 0;
public override string ToString()
{
return $"Code = {Code}, Name = {Name}, Age = {Age}";
}
}
class ExampleDemo
{
public static void Main()
{
// 创建一个新的 Student 对象
Student s = new Student
{
Code = "001",
Name = "Zara",
Age = 9
};
Console.WriteLine("Student Info:- {0}", s);
// 增加年龄
s.Age += 1;
Console.WriteLine("Student Info:- {0}", s);
Console.ReadKey();
}
}
}
Reference
擅码网面向对象基础之字段属性
刘铁猛C#教程
属性 - C# | Microsoft Learn