2015-07-29 1 views
5

Если я создаю метод расширения для Enum, называемый HasFlag, всякий раз, когда я пытаюсь вызвать HasFlag на экземпляр enum, он использует метод расширения, а не метод экземпляра. Зачем?Почему метод расширения HasFlag на Enum trump Enum.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 экземпляра?

+3

Поскольку метод экземпляра 'HasFlag' ожидает параметр. Поскольку вы не предоставляете один, он разрешает метод расширения. Попробуйте 'e.HasFlag (Foo.A);' и посмотрим. – haim770

+0

Действительно, проверьте [docs] (https://msdn.microsoft.com/en-us/library/dd782536 (v = vs.110) .aspx) и обратите внимание на подпись. Он отличается от вашей функции «HasFlag». Кроме того, нет смысла использовать 'HasFlag', если ваше перечисление не отмечено« FlagsAttribute ». –

+0

Yikes! Я выключу компьютер и пойду на хорошую ложь. Благодаря! – citizenmatt

ответ

1

Методы расширения позволяют вам «добавлять» методы к существующим типам без создания нового производного типа, перекомпиляции или иного изменения исходного типа. Методы расширения - это особый тип статического метода, но они вызываются так, как если бы они были методами экземпляра расширенного типа. Для кода клиента, написанного на C# и Visual Basic, нет никакой очевидной разницы между вызовом метода расширения и методами, которые фактически определены в типе.

Методы расширения не могут быть переопределение на экземпляра основных методов, и он не будет знать, какой метод вызвать:

Вызов неоднозначен между следующими методами

Единственный способ обойти это вызовите метод расширения с использованием стандартного синтаксиса статического метода. Таким образом, вместо этого:

e.HasFlag(); 

вы должны сделать это:

Extensions.HasFlag(e); 

Но если добавить другие параметры ваших методов расширения, то это не то же самое с основными методами, поэтому, когда вы звоните HasFlag метод, метод расширения, называемый фактически. Например:

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

Литература:

Extension Methods (C# Programming Guide)

Extension Methods, Nulls, Namespaces and Precedence in C#

+1

Да, я был глупым и пропустил параметры. Благодаря! – citizenmatt

Смежные вопросы