【问题标题】:override an enum with a custom enum in the inherited class用继承类中的自定义枚举覆盖枚举
【发布时间】:2015-09-23 16:22:06
【问题描述】:

我有一堂课:

public abstract class Criteria
{
    public virtual Enum Field
    {
        get; set;
    }
    public string FieldData;
}

我有一个枚举:

public enum MyFieldsEnum
{
    Name=1,
    Age=2,
    Gender=3,
}

我有一个继承的类:

public class MyCriteria : Criteria
{
    MyFieldsEnum myfields;
    public override MyFieldsEnum Field
    {
        get
        {
            return myfields;
        }

        set
        {
            base.Field = value;
        }
    }
}

这个想法是返回 MyFieldsEnum 而不是空白 Enum 场地。但是上面的代码不起作用,不接受 字段的 MyFieldsEnum。 它给出了错误:“Type must be enum to match overridden member Criteria.Field”

是否有可能以某种方式或其他方式?

【问题讨论】:

  • 可以使用泛型吗?
  • “不起作用”是永远足够的信息。会发生什么与你想发生什么? (但是不,你不能用不同类型的属性覆盖一种类型的属性。)
  • @JonSkeet 谢谢。我想要实现的是:我想要一个基类,但继承的类将实现他们自己的 Enum 版本。有没有办法做到这一点?
  • @DanielA.White 非常感谢。马上试试。
  • 你还没有澄清问题。你收到什么错误?是的,我可以猜到——但我不应该这么做。细节应该在问题中 - 包括动机。

标签: c# inheritance enums


【解决方案1】:

我的投票是将其更改为使用泛型。

public abstract class Criteria<TEnum>
   where TEnum : struct, IConvertable
{
     public T Field { get; set; }
}

public class MyCriteria : Criteria<MyFieldsEnum>
{
   // No need to override Field
}

请注意,C#/CLR 目前不支持枚举作为类型约束。你可以随心所欲,但这里有更多信息:Create Generic method constraining T to an Enum

【讨论】:

  • 谢谢。如何在实现的代码中将字段值读取为枚举?
  • @Satyajit 这听起来像是一个单独的问题!
【解决方案2】:

由于您无法从基类中覆盖 Enum,因此您可以使用 generics 代替,因为 EnumstructIConvertible另外,请阅读注释结束):

public abstract class Criteria<T> where T : struct, IConvertible
{
    public virtual T Field
    {
        get; set;
    }
    public string FieldData;
}

public class MyCriteria : Criteria<MyFieldsEnum>
{
    MyFieldsEnum myfields;
    public override MyFieldsEnum Field
    {
        get
        {
            return myfields;
        }

        set
        {
            base.Field = value;
        }
    }
}

另一种方法是在运行时检查它,但这风险更大,并且需要使用此类的开发人员知道从get 方法返回的EnumMyFieldsEnum

public class MyCriteria : Criteria
{
    MyFieldsEnum myfields;
    public override Enum Field
    {
        get
        {
            return myfields;
        }

        set
        {
            if (!(value is MyFieldsEnum))
            {
                throw new InvalidOperationException("Cannot set enums other than MyFieldsEnum");
            }
            base.Field = value;
        }
    }
}

注意:无论如何,在你这样做之前,你应该重新考虑 Enum 作为你的抽象类型,因为如果你考虑一下,任何将 Criteria 引用为 abstract class 的代码都必须知道您正在使用的实际 Enum 是为了做某事,所以您最好确保输入安全并重新考虑这种抽象是否真的给您带来任何好处

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-14
    • 2010-10-19
    • 1970-01-01
    相关资源
    最近更新 更多