C#中的静态成员继承,最好的方法是什么?

时间:2012-07-03 11:41:42

标签: c# inheritance static

解决这个问题的最佳方法是什么?

静态成员是所有子类的一个,我想为子类使用不同的静态成员,但是名字相同,所以我可以使用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)
    }
}

4 个答案:

答案 0 :(得分:5)

  

解决这个问题的最佳方法是什么?

不要滥用非静态方法的静态方法。很简单。

静态没有继承,并且不能以任何方式拥有继承方案。

你正在通过滥用功能来打一场战斗 - 不值得战斗。请学习正确的面向对象。

答案 1 :(得分:3)

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

class Vehicle {
    public List<string> canDo;

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

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

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

更新:根据@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");
    }
}

答案 2 :(得分:3)

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

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");
    }
}

答案 3 :(得分:2)

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

编辑(详细说明):

由于您的子类实例都具有相同的能力&#39;并且您不希望为每个需要共享列表的列表填充列表。您正在使用可能需要合成的继承:

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)
    {
    }
}

我也不会使用List<string>,而是将其封装在一个具有商业意义的类中(尽管我知道这只是一个例子)。要填充canDo列表,您可以在子类型上使用工厂或工厂方法。

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

虽然我确实提出了静态作为替代方案(因为你问的是)我绝对不会自己使用静态。