【学习资料】
> 在线文档
官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/
菜鸟教程(高级教程):https://www.runoob.com/csharp/csharp-tutorial.html
> 视频教程
腾讯学院、Siki学院
> 书籍
《C#图解教程》(第6章):https://www.cnblogs.com/moonache/p/7687551.html
【学习内容】
> 菜鸟教程:高级教程部分(属性、索引器)
> 《C#图解教程》:第六章
【属性Property】
- 使用属性的原因
- 隐藏 类外部对类的某 成员数据(_age) 进行 直接操作,将_age设置为私有成员数据 private int _age = 0;
- 在set/get访问器中赋值或获取值时,可以加入其他代码逻辑(如数值范围大小限制)
- 对类外部只开放 只读 或 只写 权限
-
class Person { private int _age = 0; // 字段:分配内存 public int Age // 属性:不分配内存 { get { return _age; } set { _age = value; } } }
- 属性是一个特殊的成员函数,包含了:set 和 get 访问器
- 属性不分配内存
- set访问器
- 拥有一个单独的、隐式的值参,名称为 value,与属性的类型相同
- 拥有一个返回类型void
- get访问器
- 没有参数
- 拥有一个与属性类型相同的返回类型
- 例如:定义一个Age属性
-
class Person { private int _age = 0; // 字段:分配内存 public int Age // 属性:不分配内存 { get // get访问器, 要有return { return _age; } set // set访问器, 包含隐藏参数value { if (value < 0) // 访问器里可以对value进行校验 { _age = 0; Debug.Log("年龄输入有误"); } else _age = value; } } } void Start() { Person person = new Person(); person.Age = 18; Debug.Log(person.Age); }
- 属性的访问权限
- 属性可以只有set或get访问器:属性只读或只写
- 只有set访问器:只写属性,此时 Debug.Log(person.Age); 就无法访问了;
-
class Person { private int _age = 0; // 字段:分配内存 public int Age // 属性:不分配内存 {set // set访问器, 包含隐藏参数value { if (value < 0) // 访问器里可以对value进行校验 { _age = 0; Debug.Log("年龄输入有误"); } else _age = value; } } }
- 只有get访问器:只读属性,此时 person.Age = 18; 就无法设置了;
-
class Person { private int _age = 0; // 字段:分配内存 public int Age // 属性:不分配内存 { get // get访问器, 要有return { return _age; } } }
- 属性可以只有set或get访问器:属性只读或只写
-
- 属性的set和get可以加访问修饰符: private protected internal
-
class Person { private int _age = 0; // 字段:分配内存 public int Age // 属性:不分配内存 { get // get访问器, 要有return { return _age; } private set // 定义成私有set访问器, 只有类内部可以访问 { if (value < 0) // 访问器里可以对value进行校验 { _age = 0; Debug.Log("年龄输入有误"); } else _age = value; } } // 私有属性set访问器,类内部可访问 public void UpdateAge(int age) { Age = age; } } void Start() { Person person = new Person(); //person.Age = 18; // 报错,私有属性set访问器,外部无法访问 Debug.Log(person.Age); }
-
- 属性的set和get可以加访问修饰符: private protected internal
- 自动实现属性
- 只声明set和get,编译器会自动创建隐藏的数据
-
class Person { public int Age // 属性:分配内存(会自动创建隐藏数据) { get; private set; } }
- 抽象属性
- 属性也可以定义为抽象属性(与抽象函数类似)
-
public abstract class Person { public abstract int Age // 抽象属性,与抽象函数类似 { get; set; } } class Student : Person { public override int Age // 子类实现 { get; set; } } void Start() { Person student = new Student(); student.Age = 18; Debug.Log(student.Age); }
【索引器Indexer】
- 定义
- 与 属性 功能基本相似,也是用set和get访问器实现,但是通过 类似数组下标[index] 的方式进行访问,相当于一个 虚拟数组
- 和属性一样,索引器也不用分配内存来存储
-
return-type this[int index] { // get 访问器 get { // 返回 index 指定的值 } // set 访问器 set { // 设置 index 指定的值 } }
- 例子:内部定义数组 private string[] namelist ,然后通过索引器访问
-
class IndexedNames { static public int size = 5; private string[] namelist = new string[size]; // 定义索引器,下标类型为[int] public string this[int index] { get { if (index >= 0 && index < size) { return namelist[index]; } else { Debug.Log("index超出范围"); return ""; } } set { if (index >= 0 && index < size) { namelist[index] = value; } } } } void Start() { IndexedNames names = new IndexedNames(); names[0] = "Zara"; // 索引器[0] names[1] = "Riz"; // 索引器[1] }
-
- 索引器重载
- 可以是不同的类型,也可以有多个参数
- int类型: public string this[int index]
- string类型: public int this[string name]
- 多参数类型: public string this[int index1, int index2]
- 访问方式:names[index1, index2]
- 注:names[index1][index2] 相当于执行 [int index] 获取到nameList[index1],然后读取string的第index2的字符
-
class IndexedNames { static public int size = 5; private string[] namelist = new string[size]; // public string this[int index] { get { if (index >= 0 && index < size) { return namelist[index]; } else { Debug.Log("index超出范围"); return ""; } } set { if (index >= 0 && index < size) { namelist[index] = value; } } } // 多参数[index1, index2]: 例如index2表示获取子串长度 // 访问方式names[index1, index2],而不是names[index1][index2] public string this[int index1, int index2] { get { return namelist[index1].Substring(0, index2); } } // [string] 获取name对应的下标index public int this[string name] { get { int index = -1; for (int i = 0; i < namelist.Length; ++i) { if (namelist[i] == name) { index = i; break; } } return index; } } } void Start() { IndexedNames names = new IndexedNames(); names[0] = "Alice"; // 索引器[0] names[1] = "Bob"; // 索引器[1] names[2] = "Cherry"; // 索引器[2] Debug.Log(names[0]); // 输出:Alice Debug.Log(names["Bob"]);// 输出:1 Debug.Log(names[2, 3]); // 输出:Che Debug.Log(names[2][5]); // 输出:r }
原文地址:https://www.cnblogs.com/shahdza/p/12239066.html
时间: 2024-09-29 02:08:49