【Unity|C#】基础篇(7)——属性(Property) / 索引器(Indexer)

【学习资料】

> 在线文档

官方文档: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可以加访问修饰符: 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,编译器会自动创建隐藏的数据
    • 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

【Unity|C#】基础篇(7)——属性(Property) / 索引器(Indexer)的相关文章

C#中方法,属性与索引器

C#中方法,属性与索引器: TODO: 1,关于系统中经常出现的通过某一字段,查询对应实体信息(可能是一条字段或一条数据和一组泛型集合) 讲解篇:1,方法,2,属性3,索引器 1,方法(1,根据状态编码返回状态名称:一条字段2,根据状态返回一条数据:实体) 1,根据状态编码返回状态名称:一条字段 /// <summary> /// 根据状态返回状态名称 /// </summary> /// <param name="value"></param

010.里式转换、命名空间、字段属性、索引器

1.is asis:判断对象和类型的兼容 兼容---true 不兼容---false 子类兼容父类 子类对象 is 父类类型 --true对象 is 类型 (对象为此类型的对象 对象为此类型的子类的对象 --true)public class Person{}public class Student:Person{} Person per=new Person();Student stu=new Student();Person person=new Student();返回true:per i

C#基础回顾(三)—索引器、委托、反射

一.前言 ------人生路蜿蜒曲折,独自闯荡 二.索引器 (1)定义: 索引器是一种特殊的类成员,它能够让对象以类似数组的形式来存取,使程序看起来更为直观,更容易编写. 定义形式如下: [修饰符] 数据类型 this[索引类型 index] { get{//获得属性的代码} set{//设置属性的代码} } 其中,修饰符包括:public,protected,private,internal,new,virtual,sealed,override, abstract,extern. (2)实现

C#字段、属性、索引器

1.字段 字段是直接在类或结构中声明的任何类型的变量. 字段是其包含类型的"成员". 类或结构可以拥有实例字段或静态字段,或同时拥有两者. 实例字段特定于类型的实例. 如果您拥有类 T 和实例字段 F,可以创建类型 T 的两个对象,并修改每个对象中 F 的值,这不影响另一对象中的该值. 相比之下,静态字段属于类本身,在该类的所有实例中共享. 从实例 A 所做的更改将立刻呈现在实例 B 和 C 上(如果它们访问该字段). 2.属性 属性是 C# 中的一等公民. 借助该语言所定义的语法,开

Unity&amp;Shader基础篇-绘制网格+圆盘

一.前言 尊重原创,转载请注明出处凯尔八阿哥专栏 上一章点击打开链接中已经画出了一个棋盘网格,首先来完善一下这个画网格的Shader,添加属性,属性包括网格的线的宽度,网格的颜色等.代码如下: Shader "Unlit/Chapter2-2" { Properties { _backgroundColor("面板背景色",Color) = (1.0,1.0,1.0,1.0) _axesColor("坐标轴的颜色",Color) = (0.0,0

Vue 2.0 深入源码分析(六) 基础篇 computed 属性详解

用法 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护,比如: <div id="example">{{ message.split('').reverse().join('') }}</div> <script> var app = new Vue({ el:'#example', data:{message:'hello world'} }) </script> 这样模板不再是简

Vue 2.0 深入源码分析(五) 基础篇 methods属性详解

用法 methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script> <title>Document&

python 基础篇 11 函数进阶----装饰器

11. 前??能-装饰器初识本节主要内容:1. 函数名的运?, 第?类对象2. 闭包3. 装饰器初识 一:函数名的运用: 函数名是一个变量,但他是一个特殊变量,加上括号可以执行函数. ?. 闭包什么是闭包? 闭包就是内层函数, 对外层函数(非全局)的变量的引?. 叫闭包 可以使用_clesure_检测函数是否是闭包  返回cell则是闭包,返回None则不是 闭包的好处: 由它我们可以引出闭包的好处. 由于我们在外界可以访问内部函数. 那这个时候内部函数访问的时间和时机就不?定了, 因为在外部,

Python心得基础篇【10】装饰器

1 def outer(func): 2 def inner(*arg, **kwargs): 3 print('123') 4 ret = func(*arg, **kwargs) 5 print('112233') 6 return ret 7 return inner 8 9 10 def home(s1, s2): 11 return 'home' 12 13 14 def show(s1, ss): 15 return 'show' 16 17 @outer 18 def f1(arg