【转载】Unity 之 C# 学习笔记(12):属性 Properties

200 阅读3分钟

原文链接

版权声明:本文为CSDN博主「Altair_Alpha_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:blog.csdn.net/Altair_alph…

正文

前篇链接:Unity 之 C# 学习笔记(11):静态类型 Static

在这节,我们来介绍属性(Properties)。你可以把属性理解为一个“智能”的变量。在外部,你可以像访问变量一样访问属性。属性的智能体现在两方面:

  • 一是可以控制变量的 访问权限
  • 二是可以对变量的读写过程做 自定义的控制

如何创建一个属性

属性本身不包含一个变量,需要与一个声明的变量相联系。属性内有两个域(访问器):getset

  1. get 就是外部读取这个属性时会执行的部分,所以需要一个与声明的类型相对应的返回值;
  2. set:是外部修改这个属性时会执行的部分,关键字 value 会存储外部传入的值。

所以最基本的,我们会这样写一个属性:

public bool isGameOver;
public bool IsGameOver
{
    get
    {
        return isGameOver;
    }
    set
    {
        isGameOver = value;
    }
}

Tips:属性名应该以 大写字母开头

如上所示,我们先创建了一个 isGameOver 变量,然后创建了对应的 IsGameOver 属性

get 访问器中,我们返回了 isGameOver 的值;

set 访问器中,我们将外部传入的值 value 赋给了 isGameOver

显然,现在我们在外部访问 isGameOver 变量和 IsGameOver 属性的效果是完全一样的。在外部看来,我们的属性是这样子的:

image.png

属性的智能之处

在面向对象的程序设计中,封装是非常重要的一种思想。我们会尽量使用 private 修饰符来保护无需对类外暴露的变量。但如果我们想创建一个 对外只能读取不能修改的变量 ,怎么做?显然这个变量不能是 public 修饰的,但 private 又会使这个变量对外不可见。

在属性中,变量的访问被分为了两个域: getset。那么我们只需要去掉 set 访问器,就可以让它关联的 private 变量实质上对外变为只读状态。但是这样会 导致 我们在类内也无法对其进行修改,所以 要使用 private set,或者 protected set,如果希望在继承类中也可修改的话。

另一方面,在 getset 中我们完全可以像在一个方法中自由操作(实际上,属性的实现就是利用了方法),所以可以在其中加入一些其它逻辑。但是也 不宜 过于复杂,因为外部的访问有很大的不确定性,可能导致一些难以预料的错误发生。

对于上面的 isGameOver 进行一些改写:

private bool isGameOver;
public bool IsGameOver
{
    get
    {
        return isGameOver;
    }
    private set
    {
        isGameOver = value;
        if (isGameOver == true)
        {
            Debug.Log("Oops, the game is over");
        }
    }
}

我们之前用到过的 Time.deltaTime 就是一个只读属性。

image.png

自动属性

如果不需要在 getset 中做额外的操作,还可以使用 自动属性。在上例中,我们先声明了 isGameOver 变量,再声明 IsGameOver 属性,看起来有些繁琐。实际上,有了属性,我们已经不需要直接访问原来的变量了。利用自动属性,我们只需要声明属性,编译器会帮我们 自动生成 一个 隐藏的变量,格式如下:

image.png

可以看到效果和上例是完全一样的。