2015-09-23 3 views
1

У меня есть класс:переопределить перечисление с настраиваемым перечислением в унаследованном классе

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 для поля. Дает ошибку: «Тип должен быть перечисляемым, чтобы соответствовать переопределенному члену Критерии. Поле»

Возможно ли это так или иначе?

+0

Вы можете использовать дженерики? –

+3

«не работает» - это * никогда * достаточно информации. Что происходит против того, что вы хотите? (Но нет, вы не можете переопределить свойство одного типа с свойством другого типа.) –

+0

@JonSkeet Спасибо. Я пытаюсь достичь: я хочу иметь базовый класс, но унаследованный класс будет реализовывать собственную версию Enum. Есть ли способ достичь этого? – Satyajit

ответ

3

Мое голосование было бы изменить его использование дженериков.

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

+0

Спасибо. Как я могу прочитать значение поля в качестве перечисления в реализованном коде? – Satyajit

+0

@ Сатяжит, что звучит как отдельный вопрос! –

1

Поскольку вы не можете переопределить Enum из базового класса можно использовать generics вместо этого, с родовыми ограничениями, поскольку Enum является struct и IConvertible (Кроме того, пожалуйста, прочитайте примечание в конце):

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

Другой способ проверить это во время выполнения, но это более рискованно и требует от разработчика, используя этот класс, чтобы знать, что возвращаемый Enum из метода get является 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; 
     } 
    } 
} 

Примечание: В любом случае, прежде чем вы сделаете это, вы должны пересмотреть Enum в качестве абстрактного типа, так как если вы думаете об этом, любой код, который будет ссылаться Criteria как abstract class будет знать, что фактическая Enum вы используете для того, чтобы что-то сделать, так что вам лучше быть безопасным и пересматривать, если эта абстракция действительно дает вам какую-либо пользу..

Смежные вопросы