views:

173

answers:

4

Why cannot I see this enum extension method? (I think I'm going crazy).

File1.cs

namespace Ns1
{
    public enum Website : int
    {
        Website1 = 0,
        Website2
    }
}

File2.cs

using Ns1;

namespace Ns2
{
    public class MyType : RequestHandler<Request, Response>
    {                        
        public override Response Handle(Request request,                                       CRequest cRequest)
        {
            //does not compile, cannot "see" ToDictionary
            var websites = Website.ToDictionary<int>(); 

            return null;
        }
    }


    //converts enum to dictionary of values
    public static class EnumExtensions
    {        
        public static IDictionary ToDictionary<TEnumValueType>(this Enum e)
        {                        
            if(typeof(TEnumValueType).FullName != Enum.GetUnderlyingType(e.GetType()).FullName) throw new ArgumentException("Invalid type specified.");

            return Enum.GetValues(e.GetType())
                        .Cast<object>()
                        .ToDictionary(key => Enum.GetName(e.GetType(), key), 
                                      value => (TEnumValueType) value);            
        }
    }
}
+15  A: 

You are trying to call the extension method as a static method on the type rather than as an instance method on an object of that type. This usage of extension methods is not supported.

If you have an instance then the extension method is found:

Website website = Website.Website1;
var websites = website.ToDictionary<int>();
Mark Byers
Should it not be WebSite website = WebSite.Website1; being an enum?
btlog
@btlog: Both are valid. In this case he's not using the actual value so it makes no difference.
Mark Byers
@btlog: the `new Website()` gives the same result as `Website.Website1` as it returns the default value, the one with underlying value of 0. Not that I recommend this syntax however :-)
Hans Kesting
Thank @Mark and @Hans. I didn't realise that this was valid. New thing for the day learnt and is on 9am, perhaps I should go home now :)
btlog
+2  A: 

this Enum e refers to an enum instance, whereas Website is actually an enum class type.

apoorv020
+2  A: 

Extension methods are just syntactic sugar and they only work with instances and not with the type. So you must call an extension method on an instance of type Website and not on the type itself, as mentioned by Mark.

For your information, In addition to what Mark said, The code gets converted as below upon compilation.

//Your code
Website website = new Website();
var websites = website.ToDictionary<int>();


//After compilation.
Website website = new Website();
var websites = EnumExtensions.ToDictionary<int>(website);

An improved version of the Extension method would be to extend the type Website only and not the Enum.

//converts enum to dictionary of values
public static class EnumExtensions
{        
    public static IDictionary ToDictionary<TEnumValueType>(this Website e)
    {                        
        if(typeof(TEnumValueType).FullName != Enum.GetUnderlyingType(e.GetType()).FullName) throw new ArgumentException("Invalid type specified.");

        return Enum.GetValues(e.GetType())
                    .Cast<object>()
                    .ToDictionary(key => Enum.GetName(e.GetType(), key), 
                                  value => (TEnumValueType) value);            
    }
}
this. __curious_geek
A: 

You need to change the signature of your extension method to use your enum, rather than the Enum type itself. That is, change Enum to Website in your extension method signature:

public static IDictionary ToDictionary<TEnumValueType>(this Website enum, ...)
Tomas Lycken