c #: Warum wird diese mehrdeutige Enumerationsreferenz nicht mit der Methodensignatur aufgelöst?

8

Betrachten Sie den folgenden Code:

%Vor%

Der Compiler beschwert sich, dass MyEnum eine mehrdeutige Referenz in dem Aufruf von Frobble () ist. Da in der aufgerufenen Methode keine Mehrdeutigkeit besteht, könnte man erwarten, dass der Compiler die Typreferenz basierend auf der Methodensignatur auflöst. Warum nicht?

Bitte beachten Sie, dass ich nicht sage, dass der Compiler dies tun sollte. Ich bin zuversichtlich, dass es einen sehr guten Grund dafür gibt. Ich möchte einfach nur wissen, was dieser Grund ist.

    
Odrade 20.08.2011, 00:51
quelle

3 Antworten

13

Paul hat Recht. In den meisten Situationen in C # denken wir "von innen nach außen".

  

Es gibt keine Mehrdeutigkeit bei der Methode, die aufgerufen wird,

Dass es für Sie eindeutig ist ist für den Compiler irrelevant. Die Aufgabe der Überladungsauflösung besteht darin, zu ermitteln, ob die Methodengruppe Frobble bei bekannten Argumenten in eine bestimmte Methode aufgelöst werden kann. Wenn wir nicht bestimmen können, was die Argumenttypen sind, versuchen wir nicht einmal eine Überladungsauflösung.

Methodengruppen, die zufällig nur eine Methode enthalten, sind in dieser Hinsicht nicht besonders. Wir müssen immer noch gute Argumente haben, bevor die Überladungsauflösung erfolgreich sein kann.

Es gibt Fälle, in denen wir von "außen nach innen" sprechen, nämlich bei der Typanalyse von Lambdas. Dies macht den Überladungsauflösungsalgorithmus außerordentlich kompliziert und gibt dem Compiler ein Problem zu lösen, das in schlechten Fällen zumindest NP-HARD ist. In den meisten Szenarien wollen wir diese Komplexität und Ausgaben vermeiden. Ausdrücke werden analysiert, indem Kindunterausdrücke vor ihren Eltern analysiert werden und nicht umgekehrt.

Allgemeiner gesagt: C # ist kein "wenn das Programm mehrdeutig ist, benutze Heuristik, um Vermutungen darüber zu machen, was der Programmierer wahrscheinlich meinte". Es ist eine "informieren Sie den Entwickler, dass ihr Programm unklar und möglicherweise gebrochen ist" Sprache. Die Teile der Sprache, die versuchen, mehrdeutige Situationen aufzulösen - wie Überladungsauflösung oder Methodentyp-Schlussfolgerung oder implizit typisierte Arrays - sind sorgfältig entworfen, so dass die Algorithmen klare Regeln haben, die Versionierung und andere reale Aspekte berücksichtigen . Wenn wir einen Teil des Programms mehrdeutig ablehnen, ist das eine Möglichkeit, dieses Designziel zu erreichen.

Wenn Sie eine "nachsichtigere" Sprache bevorzugen, die versucht herauszufinden, was Sie damit gemeint haben, sind VB oder JScript möglicherweise bessere Sprachen für Sie. Sie sind mehr "tu was ich meinte, nicht was ich gesagt habe" Sprachen.

    
Eric Lippert 20.08.2011, 01:31
quelle
6

Ich glaube, weil der C # -Compiler gewonnen hat ' t normalerweise zurück .

    
Paul Batum 20.08.2011 01:11
quelle
1

NamespaceOne und NamespaceTwo sind in derselben Codedatei definiert. Das würde bedeuten, sie in verschiedene Code-Dateien zu setzen und sie mit einer Anweisung zu referenzieren.

In diesem Fall können Sie sehen, warum die Namen kollidieren. Sie haben enum in zwei verschiedenen Namesapces benannt, und der Compiler kann nicht erraten, welcher es ist, obwohl Frobble einen NamespaceOne.MyEnum-Parameter besitzt. Anstelle von

%Vor%

verwenden

%Vor%     
Juan Ayala 20.08.2011 01:12
quelle

Tags und Links