25

I wonder why we can't add static methods (only methods, not properties) into enums? Is there any explanation for that?

It would be very useful if it was allowed.

And I also want to learn who forbids us to do it? Is it IL or C#?

Edit:

I don't want to use extension methods. Because I dont need to pass an instance of that enum. I don't need it's value there...

I want to call something like FooTypes.GetGoodFoos() not something FooTypes.BadFoo.GetSomething()

Edit 2:

Is that only me who thinks this could be more useful rather than writing this method in another class?

public enum Colors
{
    Red,
    LightRed,
    Pink,
    /* .
       .
       . */
    Green

    public static Colors[] GetRedLikes()
    {
        return new Colors[]
        {
            Colors.Red,
            Colors.LightRed,
            Colors.Pink
        }
    }
}
Yves
  • 3,752
  • 4
  • 29
  • 43
  • 1
    You can create extension methods for enums. I think that's cleaner than adding methods - static or not - to an actual enum. – bstenzel Sep 23 '14 at 10:59
  • 2
    @bstenzel But to call an extension method we need an instance of that enum. I just want to call `FooTypes.GetValues()` not `FooTypes.FirstValue.SomeMethod()` – Yves Sep 23 '14 at 11:03
  • why would you call a method on something that doesn't technically exist yet. Specially Enum the only usefull method i can see is getting the list but that it's simple reflection `Enum.GetNames(typeof(MyEnum));` – Franck Sep 23 '14 at 11:08
  • 2
    @Franck I want to create a method that returns some of the enums' values as an array. Like: `Colors.GetLightColors()` I don't think this is a bad approach... That could make my codes simpler. – Yves Sep 23 '14 at 11:10
  • ya the method i wrote return array of strings. Mentioning that MyEnum IS the enum not value of enum – Franck Sep 23 '14 at 11:11
  • @Franck But I'm also asking about IL too in this question. They don't mention it in the other question. – Yves Sep 23 '14 at 11:30
  • What benefits of embedding static methods into the Enum you are expecting? – Dmitry Sep 23 '14 at 11:34
  • @Dmitry Added an example under **Edit 2** – Yves Sep 23 '14 at 11:42

3 Answers3

9

As the other answers say, it's not possible.

I know, this does not answer your question, but I want to give an alternative to your example. Because, basically what you try to archive is already possible with flags. So let me take your "GetRedLikes" example:

[Flags]
public enum Colors : byte
{
    Transparent = 0,                                         // = 0 (00000000)
    Red         = 1 << 0,                                    // = 1 (00000001)
    LightRed    = 1 << 1,                                    // = 2 (00000010)
    Pink        = 1 << 2,                                    // = 4 (00000100)
    Green       = 1 << 3,                                    // = 8 (00001000)

    RedLikes    = Colors.Red | Colors.LightRed | Colors.Pink // = 7 (00000111)
}

Then Colors.RedLikes will contain Red, LightRed and Pink. All the magic is done by bits, as always. Your condition then should look like this:

Colors c = Colors.LightRed;
if(c & Colors.RedLikes != 0)
{
    // c is red-alike
}

Of course, this solution will not allow you to do very complex algorithms, it's no method type replacement. But it allows you to combine more than one enum in a set. If you need further functions, you have to build a method in an extra class.

Martin Braun
  • 10,906
  • 9
  • 64
  • 105
  • In my case what I would like to have is "static MyEnum Random { get { return (MyEnum)rand(minEnum, maxEnum) } } // simplified random function to pseudocode". and then use it like MyEnum x = MyEnum.Random ofc it's only a syntactic sugar and no question to do the same in other way – Andrew Feb 21 '21 at 13:46
6

I use static class for same cases:

public enum SomeEnum
{
    Item1,
    Item2,
    Item3
}

public static class SomeEnumHelper
{
    public static SomeEnum[] GetMainItems() 
    {
        return new[] {SomeEnum.Item1, SomeEnum.Item2};
    }
}
Martin Braun
  • 10,906
  • 9
  • 64
  • 105
razon
  • 3,882
  • 2
  • 33
  • 46
0

We can't add methods to enums because is how the language is made, and you are free to read the specification of the C# Language Specification

14.3 Enum members

The body of an enum type declaration defines zero or more enum members, which are the named constants of the enum type. No two enum members can have the same name.

enum-member-declarations: enum-member-declaration enum-member-declarations , enum-member-declaration enum-member-declaration: attributesopt identifier attributesopt
identifier = constant-expression

Each enum member has an associated constant value. The type of this value is the underlying type for the containing enum. The constant value for each enum member must be in the range of the underlying type for the enum.

Community
  • 1
  • 1
ale
  • 10,012
  • 5
  • 40
  • 49
  • I don't think it is possible(I am waiting to be corrected), but it is surely more simple make a pure reference type which implements your needs – ale Sep 23 '14 at 11:39
  • 2
    I know it is not possible but I just wondered why? – Yves Sep 23 '14 at 11:48
  • "And I also want to learn who forbids us to do it? Is it IL or C#?" By quoting the C# spec, you're implying that it's C#. Can you write an enum in IL that has a static method? – Tim S. Sep 23 '14 at 11:51
  • 3
    This does not answer the question – MatteoSp Sep 23 '14 at 12:08
  • I found out that `enums` are considered as `constant` in **IL**. As we can write a class to contain our static method to make it work, maybe the C# compiler could do it for us too. Right? Something like they are doing with `properties` when it adds `type getFoo()` and `void setFoo(type value)` automatically into the compiled code... – Yves Sep 23 '14 at 13:12
  • 5
    This does not answer the question. What was the reasoning behind this decision? – JounceCracklePop Mar 14 '18 at 18:06
  • 1
    This is the only answer that addresses the "why" that is the question, but still fundamentally fails to actually answer it. The quote from the spec is completely irrelevant. – Paul Childs Jun 14 '22 at 02:33