【问题标题】:Is it okay to make all variables public?可以公开所有变量吗?
【发布时间】:2014-06-18 06:21:40
【问题描述】:

我正在编写一个简单的回合制 RPG 系统。我有一个BattleScreen 类来处理井的绘制……屏幕。问题是,它必须了解我的Player 类的几乎所有信息。它的NameHP 值、MP 值、JobNameLevelExperienceMoney 等等等等。为了在屏幕上写下来。我的Draw() 方法最终会从Player 中提取几乎所有变量,并且它要求我将Player 中的几乎所有内容都公开

这让我相信让Player 类自行绘制会是一个更好的主意,但后来我得到了BattleScreen 需要调用的多个Draw() 方法。如果Player 是主要播放器(具有所有数据和名称),以及它在场边(只有精灵和 HP/MP 可见)的情况下的绘制方法,以及其他屏幕的其他方法。

这两种方式都让人感到恶心。

这两种方式中的任何一种都被认为是“正常的”吗?有没有更好的设计方法?

【问题讨论】:

  • 为什么不直接通过属性公开 Player 类的必要值?
  • 很公平,那么我的下一个问题是;必须公开我的 Player 类中的每个属性是否被认为是正常的?
  • 我对 xna 没有任何经验,所以这更多是从一般 C# 的角度来看。如果你的类有需要暴露的值,你应该通过属性来做,不管有多少。
  • 您可以使用某种Draw() 方法创建一个接口IDrawable,并让您希望能够绘制的每个类都实现该接口。然后将所有这些对象放在List<IDrawable> 中,每当您需要绘制它们时,循环该列表并调用该方法。 --- 但是那样你会混合 modelview,这通常是个坏主意。
  • @Taelia - 确实。您可以Draw() 方法(并接受@Heusters 建议)扩展到Draw(ICanvas, IDrawingContext) 并处理不同的情况。但这会将越来越多的 view 逻辑放入 model 类中。因此,您可能希望将该逻辑放入单独的 [Object]View 类中。例如PlayerView,它基本上是模型类的实例(对象)的包装器,您可以在其中处理与绘制对象相关的所有内容。您仍然需要公开属性,但只读公开不应该是有害的,对吧?

标签: c# xna-4.0


【解决方案1】:

您不应该公开任何成员变量,因为这被认为是不好的做法。
你应该使用属性。

所以而不是:

public string PlayerName;

你应该使用

private string playerName;
public string PlayerName
{ 
    get { return playerName; } 
    set { playerName = value; }
}

甚至更短

public string PlayerName { get; set; }

然后,您还可以像 Corak 已经提到的那样从外部将属性设为“只读”:

public string PlayerName { get; private set; }

然后从您的Player 内部,您可以获取并设置PlayerName 的值,但从外部,就像在您的Draw 方法中一样,您只能获取它。您还可以稍后使用其他逻辑(例如验证)扩展 getter/setter,而不会破坏任何其他代码。



注意:

注意:以下性能注意事项仅在非常罕见的情况中有效,您应该永远不要假设属性会降低性能!如果您认为您可能遇到这种情况,您应该使用不同的方法进行性能测试(即使在发布模式和优化后,分析器可能会给您错误的结果)以进行比较。

正如 Chris 正确提到的,属性可能比成员慢一点如果它们没有被 JIT 内联由于 getter/setter 的“方法调用”,这应该几乎一直发生在自动属性中)。这在大多数情况下并不相关,但在每秒许多千次调用时,它可能变得相关。在这种情况下,您应该进行性能测试以查看是否是这种情况(您需要在启用优化的发布模式下运行此类测试,而不仅仅是使用分析器!)并且只有在这种情况下可以使用公共成员。
我在我的一个程序中遇到了这样一个罕见的情况,它与每秒 10k-100k 调用之间的某个位置相关,但我们仍然只讨论 100k 调用只需几毫秒。即使在这种情况下,我建议使用属性,如果您不需要绝对的所有性能(就像我的情况一样),因为在我的情况下,可维护性更重要意见。

【讨论】:

  • 有了属性,也可以public string PlayerName { get; private set; },所以reading是公开的,但writing还是私有的。
  • @Chris:这是否决票的原因还是其他问题?因为,是的,你是对的。实际上,我在一些高性能案例(约 100.000 次调用/秒)中也使用了一些“公共成员”——将其添加为注释。
  • @Chris 我很想看看你的经验得到证明。 SO上有很多答案证明并非如此。 stackoverflow.com/a/3265377/360211
  • -1 因为性能 cmets。我知道你强烈否认它,但 hans-passant 测试超过 1000 万次调用没有任何区别。所以100k永远不可能。如果您确实看到了差异,那么您可能没有发布版本或禁用了 Jit 优化。
  • @weston:在大多数情况下是的,但在某些情况下,它可以产生(很小但存在的)差异,因为我有一个(可能是因为我有多达 8 个线程“锤击道具”)。即使不是,您也会在In such cases you should do performance test to see if this is the case (you need to run such test in release mode with optimizations enabled!) and only if so use public members. 检测到这一点(在这种高性能用例中无论如何您都会这样做),所以我认为我的笔记没有错。但是感谢您解释您的反对票...
猜你喜欢
  • 2020-10-25
  • 2014-01-02
  • 2014-03-21
  • 1970-01-01
  • 2015-11-22
  • 2015-01-20
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多