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