0
\$\begingroup\$

In a former question on SO I described a problem with a construct called 'EnumBase'.

As I sad there, I am not involved when basic implementation happened. So I'm not sure why the thinks are a they are. I only know that the code was written in times of .Net 2 and 3.5. The derived classes are useed as DataSources in ASP.Net and WinForm GUIs and also for Switch-Statements.

Here the shorted main code of a typical derivates class:

public class Elements : EnumBase<int, Elements>
{
    public static readonly Elements Element1 = Create("Number 0", 0);
    public static readonly Elements Element2 = Create("Number 1", 1);

    // This empty constuctor is the solution of the previous question
    static Elements() {}


    private static Elements Create(string text, int value) 
    {
        return new Elements() { text = text, value = value };
    }

    public static String GetElement(int id)
    {
        return BaseItemList.Single(v => v.Value == id).Text; 
    }
}

And the EnumBase inself (the parameter dosentMatter in the empty constructor is no joke):

[Serializable()]
public class EnumBase<T, E> :  IEqualityComparer<E> 
        where E : EnumBase<T, E>
{
    private static readonly List<E> list = new List<E>();
    protected string text;
    protected T value;

    protected static IList<E> BaseItemList
    {
        get
        {
            return list.Distinct(new EnumBase<T, E>(false)).ToList();
        }
    }

    protected EnumBase()
    {
        list.Add(this as E);
    }

    /// <summary>
    /// Constructor for distinct to avoid empty elements in the list
    /// </summary>   
    private EnumBase(bool dosentMatter) {}

    public string Text
    {
        get { return text; }
    }

    public T Value
    {
        get { return value; }
    }


    #region IEqualityComparer<E> Member

    // ...

    #endregion
}

The switch statemaents are also not really nice (i'm not a friend of long switch an if-else-constructs, but bring polymorphism in the code is still a very very long way):

Switch
  Case Elements.Element1.value
  ...
  Case Elements.Element2.value
  ...

As you see, you have to use .value every time, which is a nice source for bugs if you forgot it :-/

All in all living with EnumBase leaves every time a strange feeling. There is a lot of code which is to write in every derived class again and again. And a lot of things can go wrong if you create or use an EnumBase derived-class. One the other hand it works but this can be 'the' argument.

From my point of view it would be nice if I can use more types form .Net-Framework instead of own programmed types. So the Question is, is there maybe something new in .net 4.0 (or even exists in .Net before 4.0) which make this implementation (in parts) obsolete?

I would be grateful for any hint.

\$\endgroup\$
  • \$\begingroup\$ What is your intent? Why do you need such class in the first place? \$\endgroup\$ – Nikita B Aug 12 '13 at 9:22
  • \$\begingroup\$ The class was primarily designed as a "extended" enum with the possibility to use it as a data source for winform controls (especially combbox) and asp.net. \$\endgroup\$ – Micha Aug 12 '13 at 10:18
  • 3
    \$\begingroup\$ ok, let me rephrase: what your class can do what can not be done by using some IList<MyStandartDotNetEnum>? \$\endgroup\$ – Nikita B Aug 12 '13 at 10:50
  • \$\begingroup\$ This is a interesting question. In first moment I would say the static access to elements, but this would not be true. So I have to think about your point. Thanks for the moment. \$\endgroup\$ – Micha Aug 12 '13 at 11:20
  • \$\begingroup\$ @Nik: The inner implementation is a list, so all stuff "around" seems to want make items use more comfortable/easy ... but in my eyes it do not really work. If you can post your comment as answer I will mark it as solution. \$\endgroup\$ – Micha Aug 23 '13 at 6:03
2
\$\begingroup\$

So, extending my comment...

Enums are designed to represent a fixed number of states. This is their purpose. If that is what you need then nothing prevents you from using standart enum. If you want to specify items source as a collection of enum values - use IEnumerable<MyStandartEnum>, for example:

//collection of all enum values
var allVlues = Enum.GetValues(typeof(MyStandartEnum)).Cast<MyStandartEnum>();
//collection of elements which satisfy SomeCondition() (extension method)
var someValues = Enum.GetValues(typeof(MyStandartEnum)).Cast<MyStandartEnum>().Where(x => x.SomeCondition());

If you need some complicated logic added to enum, if you need to extend it, etc., that only means that enum is not the right abstraction in your case. Instead of trying to emulate enum's behaviour in some wierd abstract class, you should build a proper class to represent your data and then use generic collections (or implement your own).

\$\endgroup\$
  • \$\begingroup\$ Thanks for adding comment as answer. +1 for adding more informations. \$\endgroup\$ – Micha Aug 26 '13 at 7:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.