C#:枚举和静态类不能被继承,那么我可以用什么来代替呢?

C#:枚举和静态类不能被继承,那么我可以用什么来代替呢?,c#,class,enums,static-classes,C#,Class,Enums,Static Classes,我最近开始对我的应用程序中常用的名称使用枚举。问题是无法继承枚举。这就是目的: public enum foreignCars { Mazda = 0, Nissan = 1, Peugot = 2 } public enum allCars : foreignCars { BMW = 3, VW = 4, Audi = 5 } 当然,这是不可能的。在我发现的类似问题中,人们建议使用类来代替,比如:

我最近开始对我的应用程序中常用的名称使用枚举。问题是无法继承枚举。这就是目的:

public enum foreignCars
   {
     Mazda = 0,
     Nissan = 1,
     Peugot = 2
   }


public enum allCars : foreignCars
   {
     BMW = 3,
     VW = 4,
     Audi = 5
   }
当然,这是不可能的。在我发现的类似问题中,人们建议使用类来代替,比如:

        public static class foreignCars
    {
        int Mazda = 0;
        int Nissan = 1;
        int Peugot = 2;
    }


    public static class allCars : foreignCars
    {
        int BMW = 3;
        int VW = 4;
        int Audi = 5;
    }
但是静态类也不能被继承!因此,我必须使它们成为非静态的,并创建对象,以便能够在我的应用程序中引用这些名称,这违背了整个目的

考虑到这一点,实现我想要的最好方法是什么——拥有可继承的类似枚举的实体(这样我就不必在枚举/类/任何东西中重复汽车品牌),也不必实例化对象?这里的正确方法是什么?这是我在其他问题中找不到的部分,但是如果我遗漏了什么,请告诉我

编辑:我想指出,我已经回顾了有关枚举和静态类继承的类似问题,我完全知道这在C#中是不可能的。因此,我正在寻找一个类似问题中没有涉及的替代方案。

C#中的枚举是一个非常弱的实现。它们基本上只是命名的值。Java的枚举稍微好一点,因为它们实际上是具有特殊语义的类,所以您可以实现类似于Java的枚举的东西

public sealed class Car
{
    public static readonly Mazda = new Car(0, "Mazda", true);
    public static readonly Nissan = new Car(1, "Nissan", true);
    public static readonly Peugeot = new Car(2, "Peugeot", true);
    public static readonly BMW = new Car(3, "BMW", false);
    public static readonly VW = new Car(4, "VW", false);
    public static readonly Audi = new Car(5, "Audi", false);

    private Car(int value, string name, bool isForeign)
    {
        Value = value;
        Name = name;
        IsForeign = isForeign;
    }

    public int Value { get; }
    public string Name { get; }
    public bool IsForeign { get; }
    
    // TODO : Implement Equals and GetHashCode...
    public override string ToString() => Name;
}
请注意,这里可以创建的
Car
的实例仅在类本身中声明,并且由于构造函数是私有的,因此不能在外部构造任何实例。这与Java中的枚举非常相似,允许您在枚举中包含其他字段,而不仅仅是名称和值

还有一件事需要注意
IsForeign
被声明为
bool
。外国对你来说,可能对我来说并不陌生,所以也要考虑全球化和本土化。也许您应该通过
CountryOfManufacture
指定
Car
,或者更好的是,从.NET的文化名称空间中指定一些内容

如果你想知道我是从哪里得到enum类的灵感的……Jimmy Bogard,Automapper的作者

C#中的枚举是一个非常弱的实现。它们基本上只是命名的值。Java的枚举稍微好一点,因为它们实际上是具有特殊语义的类,所以您可以实现类似于Java的枚举的东西

public sealed class Car
{
    public static readonly Mazda = new Car(0, "Mazda", true);
    public static readonly Nissan = new Car(1, "Nissan", true);
    public static readonly Peugeot = new Car(2, "Peugeot", true);
    public static readonly BMW = new Car(3, "BMW", false);
    public static readonly VW = new Car(4, "VW", false);
    public static readonly Audi = new Car(5, "Audi", false);

    private Car(int value, string name, bool isForeign)
    {
        Value = value;
        Name = name;
        IsForeign = isForeign;
    }

    public int Value { get; }
    public string Name { get; }
    public bool IsForeign { get; }
    
    // TODO : Implement Equals and GetHashCode...
    public override string ToString() => Name;
}
请注意,这里可以创建的
Car
的实例仅在类本身中声明,并且由于构造函数是私有的,因此不能在外部构造任何实例。这与Java中的枚举非常相似,允许您在枚举中包含其他字段,而不仅仅是名称和值

还有一件事需要注意
IsForeign
被声明为
bool
。外国对你来说,可能对我来说并不陌生,所以也要考虑全球化和本土化。也许您应该通过
CountryOfManufacture
指定
Car
,或者更好的是,从.NET的文化名称空间中指定一些内容

如果你想知道我是从哪里得到enum类的灵感的……Jimmy Bogard,Automapper的作者


您遇到的一般问题是,您给枚举附加了额外的含义。一旦这样做,它就不再是枚举,而是系统中的一个概念,通常由对象表示

如果你不知道你在做什么,你很难提供更多的工作。但问题是,要附加的“额外”信息不属于枚举。它需要放在别的地方。我将提供一个简单的示例,该示例还有很多需要改进的地方,但至少代表了枚举之外的概念:

public enum allCars : int
{
    // note in general this is a bad idea, you've
    // created compile time construct to hold 
    // something that can change.
    Mazda = 0,
    Nissan = 1,
    Peugot = 2,
    BMW = 3,
    VW = 4,
    Audi = 5
}

public class Car
{
    static HashSet<allCars> foreignCars = new HashSet<allCars>(
            new allCars[] { allCars.Mazda, allCars.Nissan, allCars.Peugot });

    public Car(allCars id)
    {
        this.CarId = id;
    }

    public allCars CarId { get; }
    public bool IsForeignCar => foreignCars.Contains(this.CarId);
}
公共枚举所有车辆:int
{
//注意:一般来说,这是一个坏主意,你已经
//已创建要保存的编译时构造
//一些可以改变的东西。
马自达=0,
日产=1,
标致=2,
宝马=3,
VW=4,
奥迪=5
}
公车
{
静态哈希集foreignCars=新哈希集(
全新全车[]{allCars.Mazda,allCars.Nissan,allCars.Peugot});
公共车辆(所有车辆id)
{
this.CarId=id;
}
所有公共车辆均已损坏{get;}
public bool IsForeignCar=>foreignCars.Contains(this.CarId);
}

我已经把“这是一辆外国车”的概念转移到了汽车类本身,这可能是冒险的,但它说明了一般的观点。在编译时设置可以更改的内容(enum本身和外国汽车库)通常不是什么好事。您可能还想从设计中重构它。

您遇到的一般问题是,您给枚举附加了额外的含义。一旦这样做,它就不再是枚举,而是系统中的一个概念,通常由对象表示

如果你不知道你在做什么,你很难提供更多的工作。但问题是,要附加的“额外”信息不属于枚举。它需要放在别的地方。我将提供一个简单的示例,该示例还有很多需要改进的地方,但至少代表了枚举之外的概念:

public enum allCars : int
{
    // note in general this is a bad idea, you've
    // created compile time construct to hold 
    // something that can change.
    Mazda = 0,
    Nissan = 1,
    Peugot = 2,
    BMW = 3,
    VW = 4,
    Audi = 5
}

public class Car
{
    static HashSet<allCars> foreignCars = new HashSet<allCars>(
            new allCars[] { allCars.Mazda, allCars.Nissan, allCars.Peugot });

    public Car(allCars id)
    {
        this.CarId = id;
    }

    public allCars CarId { get; }
    public bool IsForeignCar => foreignCars.Contains(this.CarId);
}
公共枚举所有车辆:int
{
//注意:一般来说,这是一个坏主意,你已经
//已创建要保存的编译时构造
//一些可以改变的东西。
马自达=0,
日产=1,
标致=2,
宝马=3,
VW=4,
奥迪=5
}
公车
{
静态哈希集foreignCars=新哈希集(
全新全车[]{allCars.Mazda,allCars.Nissan,allCars.Peugot});
公共车辆(所有车辆id)
{
this.CarId=id;
}
所有公共车辆均已损坏{get;}
public bool IsForeignCar=>foreignCars.Contains(this.CarId);
}
我已经把“这是一辆外国车”的概念转移到了汽车类本身,这可能是冒险的,但它说明了一般的观点。把事情安排在公司