Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does HasFlag extension method on Enum trump Enum.HasFlag?

If I create an extension method on Enum called HasFlag, whenever I try to call HasFlag on an enum instance, it uses the extension method, rather than the instance method. Why?

public static class Extensions
{
  public static bool HasFlag(this Enum e)
  {
    return false
  }
}

With code:

public enum Foo
{
  A, B, C
}

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

Compiles to:

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

Why doesn't the compiler use the Enum.HasFlag instance method?

like image 537
citizenmatt Avatar asked Nov 10 '22 08:11

citizenmatt


1 Answers

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.

Extension methods cannot be override on instance main methods and it will not know which method to call:

The call is ambiguous between the following methods

The only way around this is to call your extension method using normal static method syntax. So instead of this:

e.HasFlag();

you would have to do this:

Extensions.HasFlag(e);

But if you add other parameters to your extension methods then it is not same to main methods, so when you call HasFlag method, the extension method called actually. For example:

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

References:

Extension Methods (C# Programming Guide)

Extension Methods, Nulls, Namespaces and Precedence in C#

like image 107
Behzad Avatar answered Nov 14 '22 23:11

Behzad