【问题标题】:C# extend method for Enum object枚举对象的 C# 扩展方法
【发布时间】:2015-12-15 19:12:58
【问题描述】:

我正在尝试创建扩展方法,但无法使其工作。

所以这行得通,在枚举类型示例上创建扩展方法:

public enum Pets
{
    ....
}

Above Pets 可以通过创建如下扩展方法进行扩展:

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

但是当我尝试扩展 Enum 本身时,下面的示例:

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

并尝试像下面这样使用它

Enum.something(); 

这不起作用。

我试图创建类似的方法,例如 Enum.Parse、Enum.IsDefined(c# 已经公开)。

【问题讨论】:

  • 显然Enum没有Something
  • 您必须创建Enum 的实例才能调用该方法,而不是像Enum 类上的静态方法那样调用它。
  • 我很好奇你打算用这种方法做什么?
  • @IvanStoev 我试图创建一个类似 Parse 的方法(它已经被 c# 公开了)。虽然看下面的答案,但看起来不太可能。

标签: c#


【解决方案1】:

这与 Enum 本身无关 - 但扩展方法“看起来”就像它们是 instance 方法。您不能“假装”添加静态方法,因为您目前正在尝试这样做。

你可以这样做:

Pets.SomeValue.something()

... 因为那是在“实例”(一个值)上调用扩展方法。请注意,它最终会限制价值。

【讨论】:

  • 为什么会导致拳击?
  • @roryap:因为Enum是一个引用类型。
  • 有没有办法修改代码以避免装箱?还是枚举类型的扩展方法总是如此?代码中的哪个位置发生了装箱(将值包装在 Object 中)?
  • 我发现 this 表明在将“从任何枚举类型转换为 System.Enum 类型”时会发生装箱,但 OP 并没有在任何地方转换为 System.Enum,对吧?
  • @roryap:拳击会发生在呼叫现场。这与扩展方法无关...如果您只是使用 SomeClassName.Foo(Pets.SomeValue) 调用它,您将获得完全相同的效果。
【解决方案2】:

枚举是一个类型名称。例如,您应该使用扩展方法。下一个代码工作正常:

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();
    }
}

【讨论】:

    【解决方案3】:

    Extension methods 真的很强大很有趣。为了正确创建扩展方法,您需要有一个非嵌套的静态类,然后公开一个静态方法。静态方法的第一个参数必须包含您要扩展的类型的 this 关键字。例如,如果你想专门扩展Pets enum,那么你需要有一个扩展方法正确指定参数的扩展,同样针对Enum。见下文:

    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;
        }
    }
    

    这是输出:

    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
    

    【讨论】:

      猜你喜欢
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多