1

I have a class:

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

I have an enum:

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

I have an inherited class:

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

        set
        {
            base.Field = value;
        }
    }
}

The idea is to return the MyFieldsEnum rather than the blank Enum Field. But the above code does not work and does not accept MyFieldsEnum for Field. It gives the error: "Type must be enum to match overridden member Criteria.Field"

Is it possible in some way or the other?

Satyajit
  • 1,971
  • 5
  • 28
  • 51
  • can you use generics? – Daniel A. White Sep 23 '15 at 16:23
  • 3
    "does not work" is *never* enough information. What happens vs what you want to happen? (But no, you can't override a property of one type with a property of a different type.) – Jon Skeet Sep 23 '15 at 16:24
  • @JonSkeet Thanks. What I am trying to achieve is: I want to have a base class but the inherited class will implement their own version of Enum. Is there a way to achieve that? – Satyajit Sep 23 '15 at 16:28
  • @DanielA.White Thanks a lot. Trying it now. – Satyajit Sep 23 '15 at 16:30
  • 3
    You still haven't clarified the question. What error do you receive? Yes, I could guess - but I shouldn't have to. The detail should be in the question - including the motivation. – Jon Skeet Sep 23 '15 at 16:45
  • @JonSkeet It gives the error: "Type must be enum to match overridden member Criteria.Field". – Satyajit Sep 23 '15 at 16:50
  • Right. So please edit that into the question. As I said initially, a question should never contain "the above code does not work" without explaining in what *way* it doesn't work. – Jon Skeet Sep 23 '15 at 16:52
  • @JonSkeet Sure, will do that. Thanks. – Satyajit Sep 23 '15 at 17:01

2 Answers2

4

My vote would be to change it to use generics.

public abstract class Criteria<TEnum>
   where TEnum : struct, IConvertable  // Edit: C# 7.2 TEnum:System.Enum works.
{
     public T Field { get; set; }
}

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

Be warned that C#/CLR does not at present support enum as a type constraint period to C# 7.2. You can do TEnum: System.Enum in C#7.2 , but here is more information: Create Generic method constraining T to an Enum

Community
  • 1
  • 1
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
1

Since you cannot override Enum from the base class you can use generics instead, with generic constrains since Enum is a struct and an IConvertible (Also, please read the note in the end):

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

Other way is to check this at runtime but this is more risky and will require the developer using this class to know that the returned Enum from the get method is MyFieldsEnum:

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

Note: Anyway before you do that, you should reconsider Enum as your abstract type since if you think about it, any code that will refer Criteria as an abstract class will have to know that actual Enum you are using in order to do something will it, so you better be type safe and reconsider if this abstraction really gives you any benefit.

Tamir Vered
  • 10,187
  • 5
  • 45
  • 57