2013-08-11 29 views
6

Klasa pochodna zawiera metodę "Count", która wykonuje pewne działania na klasie "Derived". Z drugiej strony mam metodę Extension, która jest również skierowana do klasy "Derived".Dlaczego metoda rozszerzenia zachowuje się inaczej?

Derived derived = new Derived(); 
derived.Count(); 

Wywołanie powyższego fragmentu spowoduje wykonanie metody "Count" wewnątrz klasy pochodnej. Dlaczego kompilator C# nie ostrzega i nie identyfikuje metody rozszerzenia w tej sytuacji. W jaki sposób środowisko wewnętrznie to obsługuje?

//Base class 
public class Base 
{ 
    public virtual string Count() 
    { 
     return string.Empty; 
    } 
} 

//Derived class 
public class Derived : Base 
{ 
    public override string Count() 
    { 
     return base.Count(); 
    } 
} 

//Extension Methods for Derived class 
public static class ExtensionMethods 
{ 
    public static Derived Count(this Derived value) 
    { 
     return new Derived(); 
    } 
} 

Odpowiedz

6

spec (§7.6.5.2) wyraźnie stwierdza, że ​​metody instancji nie metodom przedłużających:

gdy normalne przetwarzanie wywołania nie znajdzie zastosowanie metod próbuje się procesowi konstrukt jako wywołanie metody rozszerzenia.

...

Powyższe zasady oznaczają, że metody instancji mają pierwszeństwo przed metod rozszerzających, że rozszerzenie metod dostępnych w wewnętrznych deklaracji przestrzeni nazw mają pierwszeństwo przed metod rozszerzenie dostępnych w zewnętrznych deklaracji przestrzeni nazw, i że rozszerzenie metod zadeklarowane bezpośrednio w przestrzeń nazw ma pierwszeństwo przed metodami rozszerzeń zaimportowanymi do tej samej przestrzeni nazw za pomocą dyrektywy dotyczącej przestrzeni nazw. Na przykład:

Jeśli metoda instancji jest zgodna z parametrami przekazanymi, metody rozszerzenia nie są nawet brane pod uwagę.

+0

Możesz również dodać szczegóły dotyczące tego, dlaczego. Przykłady Mogę wymyślić: Zmniejszenie niejednoznaczności, a więc nie kończy się na zmianie funkcjonalności klasy podstawowej (np. Przez wywołanie twojego rozszerzenia 'Count' lub' Count' instancji 'zależnie od tego, co jest w zakresie lub określone w danym momencie) – Xcelled194

+0

Jeśli naprawdę chcesz wywołać metodę rozszerzenia zamiast normalnej, nie możesz użyć cukru syntaktycznego i musisz użyć normalnego statycznego wywołania metody: 'Derived derived = new Derived(); ExtensionMethods.Count (pochodna); ' – Alejandro

Powiązane problemy