序号 | 系列文章 |
---|---|
12 | 【C#基础】C# 文件与IO |
13 | 【C#进阶】C# 特性 |
14 | 【C#进阶】C# 反射 |
前言
🌲 大家好,我是writer桑,本章为大家介绍 C# 中的属性。
1,属性的概念
属性是 C# 中的重要成员。 属性和字段1类似,但属性提供了一种被称为访问器的灵活机制来读取、写入或计算私有字段的值。访问器是用于定义访问属性或为属性赋值时执行的语句。借助属性所定义的语法,开发者可写出兼具安全性与灵活性的代码。
2,属性的定义
属性的定义和字段类似,可以说是字段的自然延伸。属性定义包含 get 和 set 访问器的声明,其中 set 访问器可分配数据成员,get 访问器检索数据成员值。
代码示例:
using System;
public class Person
{
public string name { get; set; }
static void Main(string[] args)
{
Person p = new Person();
if(p.name == null)
{
Console.WriteLine("Person类的name属性的值为空。");
}
else
{
Console.WriteLine($"Person类的name属性的值为{p.name}。");
}
}
}
运行结果:
在上例中演示了属性定义中最简单的一种情况,不需要对访问器进行验证的读写属性。
2.1 设置初始化值
在 C# 中,属性支持在定义时设置除了默认值以外的值,可以通过在属性的右括号后设置初始值。
可以在前面示例中的 Person 类的基础上对 name 属性进行初始化赋值。
代码示例:
public string name { get; set; } = "personName";
运行结果:
在上例中,对 name 属性设置了初始化值 personName 。
3,访问器的使用
属性的访问器是一个包含有助于计算、写入或读取属性的可执行语句,其中包含 get 和 set 访问器。 当对属性进行写入值的时候,程序执行的是 set{} 中的语句,当想要读取属性中的值的时候,程序执行的是 get {} 中的语句。
在实际的项目中,可以根际不同的需求在访问器中编写所需的代码,以此创建多种不同的验证行为。
代码示例:
using System;
public class TimeExample
{
private double _seconds;
public double Hours
{
get { return _seconds / 3600; }
set
{
if (value < 0 || value > 24)
throw new ArgumentOutOfRangeException(nameof(value),
"有效范围为0 ~ 24。");
_seconds = value * 3600;
}
}
}
public class Program
{
static void Main(string[] args)
{
TimeExample time = new TimeExample() { Hours = 12 };
Console.WriteLine($"TimeExample类的Hours属性值为{time.Hours}");
}
}
运行效果:
在上例中,定义了 Hours 属性,在读取属性值方面设置了 value 值必须是在0到24的范围之内的条件,否则会引发编译器错误,这就是属性中访问器的使用。
4,访问权限限制
在 C# 中,属性的访问权限2并不是唯一的。可以创建只读属性,或者对 set 和 get 访问器提供不同的可访问性。在 set 和 get 访问器的定义前放置访问修饰符,以此来实现比在属性定义上的访问修饰符更严格的限制。其中允许放置的访问修饰符有 public、private、protected、internal 、protected internal 和 private protected。
代码示例:
using System;
public class Person
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("名字不能为空");
_firstName = value;
}
}
// 类成员的实现 ....
}
public class Program
{
static void Main()
{
Person p = new Person() { FirstName = "Adelina" };
Console.WriteLine($"Person类的FirstName属性值为{p.FirstName}");
}
}
运行结果:
在上例中,Person 类中定义了私有属性 _firstName。Person 类只能从该类的其他方法中启用 FirstName 属性值改写和读取 _firstName 属性。 _firstName 属性前面定义 private 访问修饰符,说明只有同一类或结构体中的代码才可以访问该类型或成员
5,只读属性
在属性中可以只定义 get 访问器,而不定义 set 访问器,那么这个属性就是只读属性3。但是属性不能不定义 get 访问器,会引起编译器报错。
代码示例:
using System;
public class Person
{
public Person(string firstName) => FirstName = firstName;
public string FirstName { get; } // 只读属性
// 省略实现其它类成员...
}
public class Program
{
static void Main()
{
string firstName = "Rosalind";
Person p = new Person(firstName);
Console.WriteLine(p.FirstName);
}
}
运行结果:
当定义属性时不写 get 访问器时,编译器会报错。
代码示例:
public string FirstName { set; } // 只读属性
代码效果:
6,初始化访问器
在调用上例中的只读属性时,调用方无法使用对象初始值设定项向属性分配值。若要支持初始值设定项,可以将 set 访问器设置为 init 访问器。
代码示例:
using System;
public class Person
{
public Person() { }
public Person(string firstName) => FirstName = firstName;
public string FirstName { get; init; }
// 省略实现其它类成员...
}
public class Program
{
static void Main()
{
Person p = new Person() { FirstName = "Rosalind" };
Console.WriteLine($"Person类的Firstname属性值为{p.FirstName}");
}
}
运行结果:
在上例中,不必通过 Person 类的构造函数来对属性赋值。在实现 init 访问器的基础上就可以使用对象初始值设定项向属性分配值。
7,抽象属性
在抽象类4中,不仅可以有抽象方法,还可以有抽象属性。抽象属性的声明不提供属性访问器的实现,它声明该类支持属性,而将访问器实现留给派生类。也就是抽象属性应在派生类中被实现。
代码示例:
using System;
public abstract class Person
{
public abstract string Name { get; set; }
public abstract int Age { get; set; }
}
public class Student : Person
{
private string code = "11";
private string name = "Adelina";
private int age = 0;
// 声明类型为 string 的 Code 属性
public string Code
{
get
{
return code;
}
set
{
code = value;
}
}
// 声明类型为 string 的 Name 属性
public override string Name
{
get
{
return name;
}
set
{
name = value;
}
}
// 声明类型为 int 的 Age 属性
public override int Age
{
get
{
return age;
}
set
{
age = value;
}
}
public override string ToString()
{
return "Name = " + Name + ", Age =" + Age + ", Code = " + Code;
}
}
public class Example
{
public static void Main()
{
// 创建一个新的 Student 对象
Student s = new Student();
s.Code = "21004200";
s.Name = "Rosalind";
s.Age = 21;
Console.WriteLine($"学生信息:- {s}");
}
}
代码效果:
在上例中,抽象类 Person 中声明了抽象属性 Name 和 Age,派生类 Student 在继承 Person 之后重写了这两个属性,并进行打印输出。
8,接口属性
和抽象属性类似,属性也可以在接口5上进行声明。接口属性一般没有主体,和类和结构体不同,在没有主体的情况下声明访问器不会声明自动实现的属性。接口属性可以定义默认实现,但是这样的情况非常少。
代码示例:
interface IEmployee
{
string Name { get; set; }
int Counter { get; }
}
public class Example : IEmployee
{
public static int numberOfEmployees;
private string _name;
public string Name //读写实例属性
{
get { return _name; }
set { _name = value; }
}
private int _counter;
public int Counter //只读实例属性
{
get { return _counter; }
}
// 构造函数
public Example() { _counter = ++numberOfEmployees; }
}
public class Program
{
static void Main(string[] args)
{
Example e = new Example() { Name = "Rosalind" };
Console.WriteLine($"接口属性信息, name:{e.Name}, Count:{e.Counter}");
}
}
代码效果:
点击了解更多属性的使用。
结语
🌳 以上就是 C# 属性的介绍啦,希望对大家有所帮助。感谢大家的支持。
-
字段:是在类或结构中直接声明的任意类型的变量。 字段也是类中包含类型的成员。 ↩︎
-
访问权限:控制是否可以从你的程序集或其他程序集中的其他代码中使用它们。 ↩︎
-
只读:是指文档或属性只能被读取,不能被修改或存储。 ↩︎
-
抽象类:是提供可以由子类共享的一般形式,由子类根据自己的实际情况去处理这个一般形式。 ↩︎文章来源:https://www.toymoban.com/news/detail-500965.html
-
接口:是包含类或结构可以实现相关一组功能的一个定义。 ↩︎文章来源地址https://www.toymoban.com/news/detail-500965.html
到了这里,关于【C#进阶】C# 属性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!