【问题标题】:Using Getters and Setters in Unity在 Unity 中使用 Getter 和 Setter
【发布时间】:2014-05-14 08:48:04
【问题描述】:

我还有一个关于 getter 和 setter 的问题。现在我开始使用我理解的 c# getter 和 setter。我看到的问题是,我为什么要制作如下所示的公共变量:

// Variable
private int _iRandomNumber
// Getter and setter
public int iRandomNumber
{
     get { return _iRandomNumber; }
     set { _iRandomNumber = value; }

}

我不明白这有什么意义,因为将变量设为 public 会有什么不同,因为它无论如何都将 get 和 set 放在同一个括号中?

但是,如果我这样做:

// Variable
private int _iRandomNumber
// Getter and setter
public int GetiRandomNumber { get { return _iRandomNumber; } }
public int SetiRandomNumber { set { _iRandomNumber = value; } }

然后,当我尝试单独使用我的 SetiRandomNumber 时,Unity 编译器抱怨我无法使用我的 SetProperty,因为我的 SET 中没有 GET 属性。我真的应该让它像我写的第一个例子一样,因为在我写的时候,c# 中的 Getters 和 Setters 有什么意义?

或者我应该远离它们,就像我从一开始就问的那样,像在 c++ 中一样为每个 Get 和 Set 创建函数,这样我就可以自己实际使用它们?

很抱歉提出这个新问题,但是由于它太长了,所以无法在我之前的问题中添加它作为评论。

【问题讨论】:

  • 你写了什么让 Unity 编译器抱怨?使用公共但单独的属性来获取和设置字段值而不是 .. 普通属性的原因是什么?
  • 我想要不同的 GET 和不同的 SET 的原因是我希望其他几个脚本能够读取该值,但不能更改它。虽然我只是想更改变量的另一个脚本。
  • 目前还不清楚Unity 编译器报错的原因。我不知道那里的 脚本规则。你能展示一下你是怎么做到的吗?也许你可以用privategettter/setter 来欺骗它? Example.
  • 我试过这样做:this.GetComponent().SetiDaysBeforeWeatherChange += 1; Unity 编译器:属性或索引器 ToD_Weather_Base.SetiDaysBeforeWeatherChange' cannot be used in this context because it lacks the get' 访问器 但如果这是使用 GET 和 SET 的错误方式,也许我应该更改它?并按照我应该的方式,将 GET 和 SET 放在同一个公共变量中。并且仅对于只读变量,我在没有 SET 的情况下进行 GET。
  • 你的错误是+=,为此你显然需要getter和setter。

标签: c# unity3d


【解决方案1】:

属性允许您在设置值时触发事件,例如:

public string Name {
    get { return name; }
    set {
        name = value;
        var eh = NameChanged;   // avoid race condition.
        if (eh != null)
            eh(this, EventArgs.Empty);
    }
}
private string name;
public event EventHandler NameChanged;

另一个好处是,您可以使用调试器或诊断打印语句在 getter/setter 中放置断点来跟踪设置或读取属性的时间。

【讨论】:

    【解决方案2】:

    我看不出这有什么意义,因为将变量设为 public 会有什么不同,因为它无论如何都将 get 和 set 放在同一个括号中?

    不同之处在于您将 实施细节(字段)与 API(属性)分开。您可以稍后更改实现,例如使用一个long 变量为两个int 字段提供服务。 (这只是一个随机示例。)或者您可以在 setter 中提供验证和更改通知。或者您可以在 getter 中执行惰性计算。或者,您可以从外部将该属性设为只读,但可以私下写入。名单还在继续。

    您的第二个代码声明了两个不同的属性——一个是只读的,一个是只写的,它们都由同一个变量支持。至少可以说这是非惯用的 C#,并且没有任何好处。这两个属性之间没有联系,而在第一个版本中,getter 和 setter 之间有明确的联系,因为它们是同一属性的一部分。

    需要注意的是,您的第一个示例可以使用 自动实现 属性更简洁地表达:

    // Removed unconventional "i" prefix; this follows .NET naming conventions.
    public int RandomNumber { get; set; }
    

    这会在后台创建一个私有变量,以及一个其 getter 和 setter 只使用私有变量的公共属性。稍后如果您想更改实现,可以在不影响 API 的情况下这样做。

    【讨论】:

    • 好的,我想我想要一个只读(我的 GET)和一个集(我的 SET)用于我的函数,这样我就可以从其他脚本中只读取变量或我的 SET 更改它。但是,我是否应该制作一个只读的 GET 脚本,并在我的 SET 中让它同时具有 GET 和 SET,以便我可以更改它并阅读它?很抱歉这个菜鸟问题,但我对 getter 和 setter 真的很陌生,尤其是在 C# 中。
    • @user3610422:你为什么想要一个只读属性和一个只写属性来修改相同的数据?真的不清楚你想在这里实现什么,但从根本上说,如果你要表达一种状态,你应该使用一个属性。
    • @user3610422:此外,如果您对 C# 非常陌生,那么暂时离开 Unity 并在更传统的环境中学习 C# 可能会受益匪浅。 (我个人认为一开始就编写控制台应用程序有很多价值——它可以让您专注于学习语言和核心类,而不会受到 UI 问题的负担。)
    • 嗯,好的。我想我明白它背后的想法。谢谢!会去做一些 C# 常规教程,看看是否对我有更多帮助。
    【解决方案3】:

    getter 和 setter 的优点是它们主要充当函数,因此您可以执行类似的操作

    private int _iRandomNumber;
    
    public int iRandomNumber
    {
         get { return _iRandomNumber%10;} //you can do something like this mod function 
         set { _iRandomNumber = value+1000;} //you can manipulate the value being set 
    
    } 
    

    但如果你对你的变量没有这种要求,你还不如只使用一个公共变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多