如何为每个子类继承一个具有唯一值的静态属性



我有一系列对象,让我们称之为建筑,每个对象共享特定的属性,这些属性对于该建筑是静态的,但对于每个建筑都不同,例如价格。我认为实现这一点的最佳方法是创建一个具有shared-price属性的抽象超类,并在每个子类中设置值,但我不知道如何实现。下面是我尝试过的一个例子:

using System;
public abstract class Buildings
{
   internal static int price;
   internal static int turnsToMake;
}
using System;
public class Walls : Buildings
{
    public Walls()
    {
        price = 200;
        turnsToMake = 5;
    }
}

这对构建来说很好,但如果我想在创建它之前检查价格(检查玩家是否有足够的钱),那么它只会返回一个空值。我确信这是一个超级简单的解决方案,但我想不通。有什么帮助吗?

有一个"不完整"但简单的解决方案值得考虑。如果您将基类定义为Generic类,并且在派生类中将T设置为类本身,则它将起作用。

之所以会出现这种情况,是因为.NET为每个新定义静态地定义了一个新类型。

例如:

class Base<T>
{
    public static int Counter { get; set; }
    public Base()
    {
    }
}
class DerivedA : Base<DerivedA>
{
    public DerivedA()
    {
    }
}
class DerivedB : Base<DerivedB>
{
    public DerivedB()
    {
    }
}
class Program
{
    static void Main(string[] args)
    {
        DerivedA.Counter = 4;
        DerivedB.Counter = 7;
        Console.WriteLine(DerivedA.Counter.ToString()); // Prints 4
        Console.WriteLine(DerivedB.Counter.ToString()); // Prints 7
        Console.ReadLine();
    }
}

不要使用static。Static表示Building的所有实例都具有相同的值。派生类不会继承它自己的静态副本;但是总是修改基类静态。在你的设计中,只有一个性价比和转折点ToMake。

这应该对你有用:

public abstract class Buildings
{
  internal int price;
  internal int turnsToMake;
}

然而,现在大多数人不喜欢使用字段,而更喜欢属性。

public abstract class Buildings
{
  internal int Price { get; set; }
  internal int TurnsToMake { get; set; }
}

我想在创建之前检查价格[…]

我想这就是得到静态场的方法;然而,静态行为和虚拟行为不能结合在一起。也就是说,您必须为每个子类重新声明静态字段。否则,所有子类共享完全相同的字段,并覆盖彼此的值。

另一种解决方案是使用.NET(4或更高版本)框架类库中的Lazy<T, TMetadata>类型:

public class Cost
{
    public int Price { get; set; }
    public int TurnsToMake { get; set; }
}
var lazyBuildings = new Lazy<Buildings, Cost>(
        valueFactory: () => new Walls(),
        metadata: new Cost { Price = 200, TurnsToMake = 5 });
if (lazyBuildings.Metadata.Price < …)
{
    var buildings = lazyBuildings.Value;
}

也就是说,元数据(.Metadata)现在位于实际类型(BuildingsWalls)之外,可以用来决定是否真的要构建它的实例(.Value

(由于多态性,您可以拥有一整套这样的"懒惰工厂",并根据每个工厂的元数据找到要实例化的构建类型。)

基于Uri Abramson的回答:

如果需要从基类中访问静态属性,请使用反射从T中获取值。此外,您可以强制要求必须使用派生类型的T继承Base

例如

class Base<T> where T : Base <T> {
        static int GetPropertyValueFromDerivedClass<PropertyType>(BindingFlags Flags = BindingFlags.Public | BindingFlags.Static, [CallerMemberName] string PropertyName = "")
        {
            return typeof(T).GetProperty(PropertyName, Flags)?.GetValue(null);
        }
        static int Counter{ get => GetPropertyValueFromDerivedClass(); }
}
     
        static int DoubleCounter{ return Counter*2; } //returns 8 for DerivedA and 14 for DerivedB
}

如果你有更好的方法,请发帖。

对继承人来说不是那么容易,但可行。。。


public abstract class BaseType
{
    public abstract contentType Data { get; set; }
}
public class InheritedType : BaseType
{
    protected static contentType _inheritedTypeContent;
    public override contentType Data { get => _inheritedTypeContent; set => _inheritedTypeContent = value; }
}

相关内容

最新更新