通常,您希望使所有内容尽可能少地可访问(Encapsulation)!
所以事情应该是这样的
- 尽可能为
private
(因此,这也是类型成员的默认/隐式可访问性)
- 在继承的情况下需要
protected
美元
internal
-意味着只能访问同一程序集中的所有内容(也是类型的默认可访问性--人们最常使用public
是一个坏习惯,我自己也是如此;)
- 如果它确实提供了一些全局API并且在程序集外部是必需的,则返回
public
(对于一些非常特殊和尖端的情况-例如测试-您也可以通过[InternalsVisibleTo]
expose 某些装配桥)
(也有其他情况下,你会坚持拥有更多的public
一样的东西,例如,当涉及到修改时-请参阅下面的 comments )
通常,在c#中,对任何公共内容使用properties也是一种常见的做法(例如,参见Is it bad practice to use public fields?).
简而言之:它们基本上是getter/setter方法.它们可以是backing field and implement additional logic,也可以是auto-properties,如下例所示.此外,您还可以控制set
(Ter)部分的可访问性(理论上,您can也可以控制get
部分的可访问性,但set
的可访问性高于get
是很不寻常的)
Unity甚至没有文档支持auto-properties在Inspector中使用
[field: SerializeField] public bool SomeBool { get; private set; }
...所以,公共fields不是向其他脚本提供值的only种方式.
有很多很多的方法-所以基本上可以归结为偏好和您的用例.
总的来说,我会 Select
// This is only used by this type
private bool someBool;
如果这需要由用户调整-也就是判断员
// This is only used by this type
[SerializeField] private bool someBool;
如果另一个脚本要求为read,您可以 Select
// That's the backing field approach
public bool SomeBool => someBool;
// equals
public bool SomeBool
{
get => someBool;
}
// equals
public bool SomeBool
{
get
{
return someBool;
}
}
或者如上所述,使用序列化的自动属性
[field: SerializeField] public bool SomeBool { get; private/*or protected*/set };
并且只有当其他脚本也是setthis时,您才可以使用
// For simplicity and less typing effort
// I also use this for fast prototyping and quickly expose things in the Inspector
// but this shouldn't stay the long-term code
public bool SomeBool;
对于运行时的东西,您只需坚持
// Can have a default value and behaves similar to a public field
public bool SomeBool { get; set; }
但如果需要,您也可以在判断器中显示它
[field: SerializeField] public bool SomeBool { get; set; }
自动属性可以像字段一样,也可以直接用值初始化.
Sidenote:序列化的属性带有一些关于定制Editor
实现的问题--您必须通过虚拟支持字段serializedObject.FindProperty($"<{propertyName}>k__BackingField")