2

I am trying to create an extension method but can't get it to work.

So this works, create extension method on a Type of enum example:

public enum Pets
{
    ....
}

Above Pets can be extended creating an extension method like:

public static void Myex(this Pets pet)
{
    ... 
} 

But when I try to extend Enum itself example below:

Public static void something(this Enum en)
{
    ... 
} 

And try to use it like below

Enum.something(); 

this doesn't work.

I was trying to create similar method like Enum.Parse, Enum.IsDefined (which are already exposed by c#).

PiotrWolkowski
  • 8,408
  • 6
  • 48
  • 68
Idothisallday
  • 311
  • 1
  • 3
  • 14

3 Answers3

11

This has nothing to do with Enum as such - but extension methods "look" like they're instance methods. You can't "pretend" to add static methods, as it looks like you're currently trying to do.

You would be able to do:

Pets.SomeValue.something()

... because that's calling the extension method on an "instance" (a value). It will end up boxing the value, mind you.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Why would this result in boxing? – rory.ap Dec 15 '15 at 19:23
  • @roryap: Because `Enum` is a reference type. – Jon Skeet Dec 15 '15 at 19:24
  • Is there some way to modify the code to avoid boxing? Or is that always the case with extension methods on enum types? Where in the code is the boxing (wrapping the value in an `Object`) happening? – rory.ap Dec 15 '15 at 19:34
  • I found [this](https://msdn.microsoft.com/en-us/library/aa691158%28v=vs.71%29.aspx) which indicates boxing occurs when converting "From any enum-type to the type System.Enum.", but the OP isn't converting to `System.Enum` anywhere, right? – rory.ap Dec 15 '15 at 19:37
  • @roryap: The boxing would happen at the call site. It's nothing to do with extension methods... if you just called it using `SomeClassName.Foo(Pets.SomeValue)` you'd get the exact same effect. – Jon Skeet Dec 15 '15 at 19:37
  • @roryap: Yes, they are, because they've got an extension method with an `Enum` parameter. – Jon Skeet Dec 15 '15 at 19:37
  • Oh okay, my mistake. I thought your answer was calling `Myex` when in fact it's calling `something`. I see it now. – rory.ap Dec 15 '15 at 19:39
3

Enum is a type name. You should use extension methods for instance. Next code works fine:

public static class A
{
    public static void DoWork(this Enum en)
    {
        Console.WriteLine(en);
    }

    public static void DoWork(this int en)
    {
        Console.WriteLine(en);
    }
}

public enum Pets
{
    Cat,
    Dog
}

internal class Program
{
    private static void Main(string[] args)
    {
        var cat = Pets.Cat;
        //Enum.DoWork(); doesn't work
        cat.DoWork(); // works fine
        //int.DoWork(); doesn't work
        5.DoWork(); // works fine
        Console.ReadKey();
    }
}
Vadim Martynov
  • 8,602
  • 5
  • 31
  • 43
1

Extension methods are really powerful and fun. In order to correctly create an extension method you need to have a non-nested static class that then exposes a static method. The static method's first parameter must include the this keyword of the type that you're extending. For example if you want to extend the Pets enum specifically, then you need to have an extension whose extension method correctly specifies the parameter, likewise for targeting Enum. See below:

public class Program
{
    static void Main()
    {
        Console.WriteLine("Grizzlies live in water = " + Pets.NorthAmericanGrizzly.LivesInWater());
        Console.WriteLine("Fish live in water = " + Pets.Fish.LivesInWater());
        Console.WriteLine("Cat is a pet enum = " + Pets.Cat.IsPetEnum());
        Console.WriteLine("Date Time Kind of UTC is a pet enum = " + DateTimeKind.Utc.IsPetEnum());

        Console.ReadLine();
    }
}

public enum Pets
{
    Dog,
    Cat,
    Fish,
    Shark,
    NorthAmericanGrizzly
}

public static class PetExtensions
{
    public static bool LivesInWater(this Pets pet)
    {
        return pet == Pets.Fish || pet == Pets.Shark;
    }
}

public static class EnumExtensions
{
    public static bool IsPetEnum(this Enum @enum)
    {
        return @enum is Pets;
    }
}

Here is the output:

Grizzlies live in water = False
Fish live in water = True
Cat is a pet enum = True
Date Time Kind of UTC is a pet enum = False
David Pine
  • 23,787
  • 10
  • 79
  • 107