在C#中,静态成员继承的最佳方式是什么?

在C#中,静态成员继承的最佳方式是什么?,c#,inheritance,static,C#,Inheritance,Static,解决这个问题的最好办法是什么 静态成员是所有子类的一个成员,我希望子类使用不同的静态成员,但名称相同,这样我就可以使用vehicle.canDo;这将根据vechicle实例的实际类提供不同的数组 我可以从canDo数组中删除静态值,但是同一子类的所有实例在canDo数组中应该始终具有相同的值,因此没有必要在每个实例中都使用canDo数组,这将是很大的内存浪费,因为我将有太多此类的实例 class Vehicle { public static List<string> ca

解决这个问题的最好办法是什么

静态成员是所有子类的一个成员,我希望子类使用不同的静态成员,但名称相同,这样我就可以使用vehicle.canDo;这将根据vechicle实例的实际类提供不同的数组

我可以从canDo数组中删除静态值,但是同一子类的所有实例在canDo数组中应该始终具有相同的值,因此没有必要在每个实例中都使用canDo数组,这将是很大的内存浪费,因为我将有太多此类的实例

class Vehicle {
    public static List<string> canDo;

    static Vehicle() {
        canDo = new List<string>(); 
        canDo.Add("go");
    }
}

class Plane : Vehicle {
    static Plane() {
        canDo.Add("fly");
    }
}

class Ship : Vehicle {
    static Ship() {
        canDo.Add("sail");
    }
}



class Main {
    static void Main(string[] args) {
        Vehicle plane = new Plane();
        Vehicle ship = new Ship();

        plane.canDo; // Contains (go, fly and sail) i want only (go and fly)
        ship.canDo; // Contains (go, fly and sail) i want only (go and sail)
    }
}
class车辆{
公共静态列表canDo;
静态车辆(){
canDo=新列表();
canDo.添加(“go”);
}
}
飞机类别:汽车{
静态平面(){
canDo.添加(“fly”);
}
}
船舶类别:车辆{
静态船舶(){
canDo.添加(“帆”);
}
}
班长{
静态void Main(字符串[]参数){
车辆平面=新平面();
车辆船=新船();
plane.canDo;//包含(出发,飞行和航行)我只想要(出发,飞行)
ship.canDo;//包含(出发、飞行和航行)我只想要(出发和航行)
}
}

您需要每个类型的
canDo
列表的实例。因此,您可以通过构造函数传入集合,也可以在子类型级别上使用静态

编辑(详细说明):

由于您的子类实例都具有相同的“能力”,并且您不想为每个子类填充一个列表,因此您需要一个共享列表。您使用的是继承,可能需要合成:

public abstract class Vehicle
{
    protected List<string> canDo;

    protected Vehicle(List<string> canDo)
    {
        this.canDo = canDo;
    }
}

public class Plane : Vehicle
{
    public Plane(List<string> canDo) : base(canDo)
    {
    }
}
公共抽象类车辆
{
受保护名单canDo;
受保护车辆(列表canDo)
{
this.canDo=canDo;
}
}
公共类飞机:运载工具
{
公共飞机(列表canDo):底座(canDo)
{
}
}
我也不会使用
列表
,而是将其封装在一个有商业意义的类中(尽管我知道这只是一个示例)。要填充
canDo
列表,可以使用子类型上的工厂或工厂方法

有很多方法可以做到这一点,你需要找到一些舒适的方式

虽然我提出了一个静态作为替代(因为你问它),我肯定不会使用静态为这自己

解决这个问题的最好办法是什么

不要对非静态的事物滥用静态方法。就这么简单

静态没有继承性,也不能以任何方式具有继承场景


您正在通过滥用某个功能进行战斗-不值得战斗。请学习正确的对象定向。

您不需要静态变量和构造函数,只需添加基本构造函数即可(默认情况下,
:base()
是可选的):

class车辆{
公开名单坎多;
车辆(){
canDo=新列表();
canDo.添加(“go”);
}
}
飞机类别:汽车{
平面():基(){
canDo.添加(“fly”);
}
}
船舶类别:车辆{
Ship():base(){
canDo.添加(“帆”);
}
}
更新:根据@Eben Roux的评论-

public abstract class Vehicle {
    protected static List<string> _canDo;
    protected abstract List<string> getCanDo();
    public List<string> canDo{
        { get {
               var _cando = new List();
               _cando.AddRange(Vehicle._canDo);
               _cando.AddRange(this.getCanDo());
               return _cando;
              }
        }
    }
    static Vehicle() {
        _canDo = new List<string>(); 
        _canDo.Add("go");
    }
}

class Ship : Vehicle {
    protected static List<string> childCanDo;
    protected override getCanDo(){
        return Ship.childCanDo;
    }
    static Ship() {
        childCanDo.Add("sail");
    }
}
公共抽象类车辆{
受保护静态列表_canDo;
受保护的抽象列表getCanDo();
公开名单{
{得到{
var_cando=新列表();
_可添加范围(车辆);
_AddRange(this.getCanDo());
返回_cando;
}
}
}
静态车辆(){
_canDo=新列表();
_canDo.添加(“go”);
}
}
船舶类别:车辆{
受保护的静态列表childCanDo;
受保护的覆盖getCanDo(){
返回Ship.childCanDo;
}
静态船舶(){
childCanDo.添加(“帆”);
}
}

注意,您还可以使用
new
隐藏基类的
canDo

class Vehicle
{
    public static List<string> canDo = new List<string>() { "go" };   
}

class Plane : Vehicle
{
    public new static List<string> canDo = new List<string>(Vehicle.canDo);
    static Plane()
    {
        canDo.Add("fly");
    }
}
class车辆
{
public static List canDo=new List(){“go”};
}
飞机类别:汽车
{
公共新静态列表canDo=新列表(Vehicle.canDo);
静态平面()
{
canDo.添加(“fly”);
}
}

在我脑海中,从canDo中删除“static”限定符应该可以解决这个问题。我不相信在保持属性静态的情况下实现这一点。事实上,当在任何项(方法、属性、类)中使用static时,该项对于整个应用程序只有一个实例(实际上是一种实例)(这一点很重要,它们将具有相同的生命周期)。虽然措辞非常不同,但问题是相同的OP关注的是,比如说,Ship将拥有自己的
canDo
集合,并且每个实例实际上都是重复的(希望这是有意义的)。如果你不会有太多的例子,那就没什么错;否则,可以通过以某种方式注入
canDo
集合或检索它来共享状态。@EbenRoux-thanx解释一下。我错过了那一点。因此,您仍然可以保留静态基列表,并与子类连接。。。我更新了一点答案。。。我还没有测试代码,但希望想法很清楚。。。。。但是继承的整个概念都消失在这里了。。。正如在其他答案中所说,静态在这里没有位置。同意:)---然而,我认为静态确实有其位置,但它需要一些仔细的考虑和设计。实现类级(而不是实例级)数据而不重复代码的“正确”方法是什么?不要这样做。基本上实现了单例。在需要的地方引用容器实例。你可以重复一个方法/引用,但不能重复实例数据。如果这能让你的工作更容易,为什么不重复呢?我写OO代码不是为了写OO代码——我写OO代码是因为它应该帮助我很好地解决问题。如果它不能很好地帮助解决问题,那就是
class Vehicle
{
    public static List<string> canDo = new List<string>() { "go" };   
}

class Plane : Vehicle
{
    public new static List<string> canDo = new List<string>(Vehicle.canDo);
    static Plane()
    {
        canDo.Add("fly");
    }
}