为什么枚举上的HasFlag扩展方法胜过枚举.HasFlag

本文关键字:枚举 HasFlag 方法 扩展 为什么 | 更新日期: 2023-09-27 18:05:37

如果我在Enum上创建一个名为HasFlag的扩展方法,每当我试图在枚举实例上调用HasFlag时,它都会使用扩展方法,而不是实例方法。为什么?

public static class Extensions
{
  public static bool HasFlag(this Enum e)
  {
    return false
  }
}
与代码:

public enum Foo
{
  A, B, C
}
public void Whatever()
{
  Foo e = Foo.A;
  if (e.HasFlag())
  {
    // ...
  }
}

编译:

public void Whatever()
{
  Foo e = Foo.A;
  if (Extensions.HasFlag(e))
  {
    // ...
  }
}

为什么编译器不使用Enum.HasFlag实例方法?

为什么枚举上的HasFlag扩展方法胜过枚举.HasFlag

扩展方法使您能够向现有类型"添加"方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊类型的静态方法,但是调用它们时就好像它们是扩展类型上的实例方法一样。对于用c#和Visual Basic编写的客户端代码,调用扩展方法和在类型中实际定义的方法之间没有明显的区别。

扩展方法不能在实例主方法上重写,它将不知道调用哪个方法:

以下方法之间的调用是二义性的

解决这个问题的唯一方法是使用普通的静态方法语法调用扩展方法。所以不用这个:

e.HasFlag();

你必须这样做:

Extensions.HasFlag(e);

但是如果你添加其他参数到你的扩展方法,那么它是不一样的主方法,所以当你调用HasFlag方法,扩展方法实际上调用。例如:

public static bool HasFlag(this Enum e, bool isNullable)
{
    return false;
}

引用:

扩展方法(c#编程指南)

c#中的扩展方法、空值、命名空间和优先级