在父类中创建可重写的枚举

时间:2018-04-03 10:53:22

标签: c# inheritance enums

我想创建一个嵌套结构,其中每个类代表一个国家/地区,继承相同的父类Country。每个子类都应该有一个表示不同状态States的枚举。

目标是能够选择一个国家,然后选择其中一个州。

内容将保存在Dictionary<Tuple<string, Type>, object>字典中Type CountryCountry.States

我尝试使用名为interface的{​​{1}}制作abstract class / enum,但这不起作用,因为它是一种类型定义。

有解决方法吗?

States

5 个答案:

答案 0 :(得分:3)

您的设计存在缺陷,您需要使用属性创建一个Country类。 public string[] States { get; set; }

然后创建Country类的实例(对象),每个类都设置States所需的项目:

var usa    = new Country { Name = "USA",    States = new[] { "Alabama", ... } };
var canada = new Country { Name = "Canada", States = new[] { ... } };
// etc

答案 1 :(得分:1)

您有几个选择:

您可以在运行时创建一个枚举(请参阅此处:Dynamically create an enum),但我认为这并不适合您的需求,因为我想您已经下了枚举编码易于使用的路线。

你可以实现一个类型安全的枚举模式(参见这里:typesafe enum pattern),但是更多的编码只是为了能够在编写逻辑的其余部分时使用模仿枚举的设计。

我的建议是使用字典并建立你的状态&#39;在设置文件或外部数据源的实例化中。毕竟,国家及其州/市/等确实会不时更改名称。将自己锁定在一个像你所瞄准的硬编码情境中并不会支持未来的变化。

祝你好运!

[来自camilo-terevinto的回复后编辑]

答案 2 :(得分:1)

虽然我当然同意您的设计很可能存在缺陷,因为您需要数百个课程和枚举,但我完全不同意其他答案,而且#34;这是不可能的&#34;。

使用泛型(while keeping in mind you cannot restrict entirely to Enums)肯定是可能的:

public abstract class Country<TStates> 
    where TStates: struct, IConvertible, IFormattable, IComparable
{
    public abstract TStates[] States { get; }
}

public enum UnitedStatesStates
{
    WhoCares, WhoCares2
}

public class UnitedStatesCountry : Country<UnitedStatesStates>
{
    public override UnitedStatesStates[] States { get; }
}

现在,我非常怀疑这将在(不那么长)的术语中有用。

答案 3 :(得分:1)

你要求enum是可继承的,如果你不使用enum,这是可能的,但是有static public成员的类(可以继承并拥有每种类型的不同成员集)。它的行为几乎与枚举一致:

public class Country1
{
    public static State State1 { get; } = new State("State 1");
    public static State State2 { get; } = new State("State 2");
    ...
}

应该清楚Country1.State1是什么,对吗? State可以是一个比string更复杂的对象。正如您所见,它并不需要继承,因为国家将州定义为不同的成员。

您可以遵循相同的原则来实现对象的长Planet.Continent.Country.State.Province.Town.Street.Hause ..

你说

  

内容将保存在字典Dictionary<Tuple<string, Type>, object>中,其中的类型为CountryCountry.States

唐&#39;吨。这些是不同的类型,这是一个关键的不良选择。如果您需要枚举(查找)状态,则只需将另一个成员添加到Country

public static IEnumerable<State> States
{
    get
    {
        yield return State1;
        yield return State2;
        ...
    }
}

然后搜索的东西可以是一个简单的linq:

var stateAInCountry1 = ...Countries.OfType<Contry1>().Single().States.Single(o => o.Name == "A");
var countriesWithStateA = ...Countries.Where(o => o.States.Any(o => o.Name == "A"));

不确定通过引入字典解决了什么问题,但如果您提供了一种易于迭代的方法,则可以使用正确的键初始化其他数据结构。

答案 4 :(得分:0)

我不太清楚,除了被编译器提醒以定义这些不同的(!)枚举之外,还有什么想要实现的。

实际上他们没有任何共同之处,因此编译器和你都无法利用该合同。

您可以做的是将其声明为

public abstract string[] States {get;}

并从您在派生类中定义的各个枚举中获取这些字符串。然后常见的事情可能是你想要字符串结果用于提供信息或其他目的。