实现“虚拟静态”可能有什么好方法?使用简单的示例案例

问题描述:

首先,让我明确一点,这不是虚拟静态为什么不起作用的另一个问题,因此请避免回答编译器如何看到虚拟和静态或将其标记为这些问题的重复,但是如果您知道任何符合我的示例的答案,请随时链接并标记重复。实现“虚拟静态”可能有什么好方法?使用简单的示例案例

现在,通过摸索如何实现的东西,会一直用此方式解决,也就是很多人说:“我甚至不知道你为什么会需要做的”和人们想的几个例子问同样的问题,因为我有很多不同的例子,所以我很难与其他人的答案联系起来。

所以,在这个游戏中,我想让我有一个简单的InventoryItem系统。从virtual classItem继承了Inventory类可以识别

public class Item { 
    public virtual static Sprite getIcon(); 
    public virtual static string getName(); 
} 

public class Stone : Item { 
    static Sprite icon; 
    static string name = "Stone"; 

    public override static Sprite getIcon(){ 
     return icon; 
    } 
    public override static string getName(){ 
     return icon; 
    } 

    // ... 
} 

所以思想基本上是每一个Stone股在Inventory相同icon和所有的石头具有相同的名称/标题,说使用调试消息或给玩家一些他正在看或正在拾取的信息。

现在我所有的勇气告诉我,最好的做法是,Sprite应该是static,因为在InventoryStone所有实例应该表现出同样的icon。但是,各种物品也应该有Sprite,因此他们应该用inherit共同get-方法来检索这些。

于是我想出了两个备选方案感到传统错误或overkillishly错误。

1)使get - 方法非static,让他们返回静态成员的内容。这是非常规的,因为它会为每个实例返回值相同的每个实例的开销。

编辑:纠正,没有额外的开销,因此这种方法是要走的路。

2)请存储所有的精灵/名称和基于给定对象的类型返回他们一些大师班。首先,我不喜欢使用类型比较/检查,因为我觉得如果可以的话,最好避免这样做。但即便如此,我觉得像这样的解决方案是矫枉过正这些琐碎的任务返回一个stringSprite参考

所以,除非我失去了一些东西,有没有实现这一点的直接的方法是什么?还是我的两种方法之一比我认为的要好?

PS:我要实现这一个团结的比赛,因此,如果统一提供的解决方案我所有的耳朵。

+1

*这是非常规的,因为它会为类的每个实例开销,而每个实例的返回值都是相同的。*虚拟方法没有每个实例的开销。 – PetSerAl

+0

@PetSerAl我可能使用了错误的术语。但是你是否认为没有内存/性能的缺点让所有的方法都不使用静态方法? – Chexxor

+1

@Chexxor正确,没有任何惩罚,只需制作一个引用私有静态字段的普通虚拟方法即可。 –

在罗马,入乡随俗做。:)

如果使用C#那么我建议避免Java风格的编码。

例如方法名称是PascalCase而不是camelCase,而C#也有properties而不是getter/setter方法。因此,这里是我的建议:

public abstract class Item 
{ 
    public abstract Sprite Icon { get; } 

    public abstract string Name { get; } 
} 

public class Stone : Item 
{ 
    private static readonly Sprite icon = Sprite.Create(/* parameters omitted */); 

    private const string name = "Stone"; 

    // expression-bodied member: supported as of C# 6 
    public override Sprite Icon => icon; 

    // traditional propery getter 
    public override string Name 
    { 
     get 
     { 
      return name; 
     } 
    } 
} 

你可以看到什么位置:

  • 您可以覆盖性能和标有abstractvirtualoverride关键字的方法。我制作了Item类,其属性为abstract,因此我不需要实现Item类中的属性,并且只能派生类型如Stone,它们必须重写属性。
  • 由于icon字段的值不会改变,所以我应用了readonly关键字以便它不能被更改。
  • name字段可能也readonly但不是static readonly string领域,我们使用const关键字,这使得name场不仅static,而且它的价值不能被改变。 请注意:static readonlyconst表现不同,请参阅here
  • 重写的属性有两种形式:Name属性以传统的C#方式实现,Icon属性通过新的expression-bodied member功能实现。

总结一下,没有冒犯性,我的意图只是说明如何在更多的C#中实现您的解决方案,而这看起来不像Java。

+0

这个答案证明非常有用!我不知道来自Java的是那么明显;)无论如何,这些编码技巧超过了我的要求,但正是我所需要的,谢谢。 – Chexxor

随着一些澄清提意见,我发现我说的第一个解决方案实际上是直截了当的答案,我一直在寻找。只需将变量设为静态,但继承的/ overriden方法是非静态的,但使用它来检索静态值。

public class Item { 
    public virtual Sprite getIcon(); 
    public virtual string getName(); 
} 

public class Stone : Item { 
    static Sprite icon; 
    static string name = "Stone"; 

    public override Sprite getIcon(){ 
     return icon; 
    } 
    public override string getName(){ 
     return icon; 
    } 

    // ... 
}