2012-03-23 8 views
17

Jak rozumiem, każdy język może mieć własny program obsługi dynamic, więc stosowane są odpowiednie reguły. Nie jestem pewien, czy poniższe informacje są poprawne/niepoprawne; myśli?Czy należy stosować metodę opartą na interfejsie, która używa "dynamicznego" nadal spełnia zasady rozdzielczości metody C#?

Scenariusz: dwa interfejsy (jeden realizuje drugi) z pewnymi metodami:

public interface IA { 
    void Bar(object o); 
} 
public interface IB : IA { 
    void Foo(object o); 
} 

i podstawowym realizacja:

public class B : IB { 
    public void Foo(object o) { Console.WriteLine("Foo"); } 
    public void Bar(object o) { Console.WriteLine("Bar"); } 
} 

Teraz, z normalnym C# (bez dynamic), możemy uzyskać dostęp do metody IA od celu typu: IB:

IB b = new B(); 
var o = new { y = "z" }; 
b.Foo(o.y); // fine 
b.Bar(o.y); // fine 

Teraz celowo dodać dynamic do argumentów, które sprawia, że ​​przetwarzanie całego użycie invoke dynamic (jak w ogólnym przypadku Rezolucja ta może mieć wpływ na przeciążenie, choć nie będzie tutaj):

IB b = new B(); 
dynamic x = new {y = "z"}; 
b.Foo(x.y); // fine 
b.Bar(x.y); // BOOM! 

która nie z RuntimeBinderException:

'IB' nie zawierają definicji dla 'bar'

Teraz to co mówi i s całkowicie poprawne, tak jak IBnie ma ma metodę Bar. Jednak, jak pokazano w pierwszym przykładzie: w normalnych regułach C# oczekiwano, że ponieważ typ deklaracji celu jest interfejsem (IB), inne interfejsy znane jako implementowane (tj. IA) są sprawdzane jako część rozdzielczości przeciążania.

A więc: czy to błąd? Czy mogę to źle odczytać?

+0

+1 Interesujące. Zastanawiam się, czy DLR oferuje mniejsze wsparcie dla tego rodzaju rzeczy w przeciwieństwie do kompilatora/CLR. Zakładam, że DLR odpowiada za próbę rozwiązania połączenia? –

+0

@ Adam, rozumiem, że dla połączeń opartych na odbiciu, istnieje dostawca specyficzny dla języka, dokładnie w celu przestrzegania konwencji językowych, np. 'Microsoft.CSharp.RuntimeBinder.Binder' –

+0

Czy obserwujesz to samo z dziedziczeniem klasy próbującym wywołać podstawowe metody? (W przeciwieństwie do odziedziczonych metod interfejsu). –

Odpowiedz

6

Jest to dobrze znane ograniczenie spoiwa, zadawane kilka razy w SO i temat this feedback article. Zacytuję odpowiedź Microsoftu:

To był obszar, który wyraźnie określiliśmy na podstawie czasu, kiedy wysyłamy C# 4.0 i chcielibyśmy powtórzyć to. Ten konkretny przypadek metod ISet/IList, które są faktycznie zdefiniowane w ICollection, jest najbardziej widocznym miejscem, gdzie niekopywanie się przez interfejsy macierzyste niepotrzebnie ogranicza zasięg dynamicznego wiązania w C#.

Mamy nadzieję, że wkrótce dodamy takie wsparcie, ale obecnie problem ten znajduje się tuż poniżej naszej linii cięcia błędów. Problem nie zostanie naprawiony, aby wskazać, że obecnie nie śledzimy, aby rozwiązać ten problem w następnej wersji programu Visual Studio. Ponownie aktywujemy ten błąd w ciągu następnego roku, jeśli uzyskamy więcej, niż można się tego spodziewać na naszej liście błędów błędów, lub jeśli ponownie przejdziemy do błędu w następnej wersji.

Co się jeszcze nie stało, Afaiku. Artykuł nie ma wielu głosów.

Powiązane problemy