为什么我看不到这个枚举扩展方法?

9

为什么我看不到这个枚举扩展方法?(我觉得我要疯了)。

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);            
        }
    }
}
4个回答

15

你试图在类型上以静态方法的方式调用扩展方法,而不是在该类型的对象实例上作为实例方法调用。此使用扩展方法的方式是不被支持的。

如果你有一个实例,那么扩展方法就能被找到:

Website website = Website.Website1;
var websites = website.ToDictionary<int>();

3
不应该是枚举类型吗?WebSite website = WebSite.Website1; - btlog
1
@btlog:两种都是有效的。在这种情况下,他没有使用实际值,因此没有区别。 - Mark Byers
@btlog:new Website()Website.Website1给出相同的结果,因为它都返回默认值,即底层值为0的默认值。但我并不推荐这种语法 :-) - Hans Kesting
感谢@Mark和@Hans。我之前没有意识到这是有效的。今天学到了新东西,现在已经是早上9点了,也许我应该回家了 :) - btlog

2

扩展方法只是一种语法糖,它们仅适用于实例而不是类型。因此,您必须在Website类型的实例上调用扩展方法,而不是在类型本身上调用,正如Mark所提到的那样。

此外,值得注意的是,在编译时,代码会转换为以下形式。

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


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

一个“改进版本”的扩展方法会是仅扩展类型为Website而非枚举。
//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);            
    }
}

2

this Enum e 是指一个枚举实例,而 Website 则是一个枚举类类型。


0

您需要更改扩展方法的签名,以使用您自己的枚举,而不是Enum类型本身。也就是说,在您的扩展方法签名中将Enum更改为Website

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接