enum define c# enums namespaces

define - enum string c#



c#: ¿Por qué no se resuelve esta referencia de enumeración ambigua utilizando la firma del método? (3)

Creo que es porque el compilador de C # normalmente no dará marcha atrás .

Considera el siguiente código:

namespace ConsoleApplication { using NamespaceOne; using NamespaceTwo; class Program { static void Main(string[] args) { // Compilation error. MyEnum is an ambiguous reference MethodNamespace.MethodClass.Frobble(MyEnum.foo); } } } namespace MethodNamespace { public static class MethodClass { public static void Frobble(NamespaceOne.MyEnum val) { System.Console.WriteLine("Frobbled a " + val.ToString()); } } } namespace NamespaceOne { public enum MyEnum { foo, bar, bat, baz } } namespace NamespaceTwo { public enum MyEnum { foo, bar, bat, baz } }

El compilador se queja de que MyEnum es una referencia ambigua en la llamada a Frobble (). Dado que no existe ambigüedad en el método que se está llamando, se puede esperar que el compilador resuelva la referencia de tipo en función de la firma del método. ¿Por qué no?

Tenga en cuenta que no estoy diciendo que el compilador debería hacer esto. Estoy seguro de que hay una muy buena razón para que no sea así. Simplemente me gustaría saber cuál es esa razón.


NamespaceOne y Namespace Two se definen en el mismo archivo de código. Eso sería equivalente a ponerlos en diferentes archivos de código y hacer referencia a ellos mediante el uso de la declaración.

En ese caso, puede ver por qué los nombres entran en conflicto. Igualmente has llamado a enum en dos nombres diferentes y el compilador no puede adivinar de cuál se trata, aunque Frobble tiene un parámetro NamespaceOne.MyEnum. En lugar de

MethodNamespace.MethodClass.Frobble(MyEnum.foo)

utilizar

MethodNamespace.MethodClass.Frobble(NamespaceOne.MyEnum.foo)


Paul está en lo cierto. En la mayoría de las situaciones en C # razonamos "de adentro hacia afuera".

no hay ambigüedad en el método que se está llamando,

Que no le resulte ambiguo es irrelevante para el compilador. La tarea de la resolución de sobrecarga es determinar si el grupo de métodos Frobble se puede resolver con un método específico dados los argumentos conocidos . Si no podemos determinar cuáles son los tipos de argumento, entonces ni siquiera intentamos hacer una resolución de sobrecarga.

Los grupos de métodos que simplemente contienen un solo método no son especiales a este respecto. Todavía tenemos que tener buenos argumentos antes de que la resolución de sobrecarga pueda tener éxito.

Hay casos en los que razonamos de "afuera hacia adentro", es decir, cuando hacemos un análisis tipo de lambdas. Hacerlo hace que el algoritmo de resolución de sobrecarga sea extremadamente complicado y le da al compilador un problema para resolver que es al menos NP-HARD en casos malos. Pero en la mayoría de los escenarios queremos evitar esa complejidad y gasto; las expresiones se analizan mediante el análisis de las subexpresiones infantiles antes que sus padres , y no al revés.

De manera más general: C # no es "cuando el programa es ambiguo usa heurística para hacer conjeturas sobre lo que el programador probablemente quiso decir" lenguaje. Es un "informar al desarrollador que su programa no está claro y posiblemente roto". Las partes del lenguaje diseñadas para tratar de resolver situaciones ambiguas, como resolución de sobrecarga o inferencia de tipo de método o matrices implícitamente tipadas, están cuidadosamente diseñadas para que los algoritmos tengan reglas claras que tengan en cuenta el control de versiones y otros aspectos del mundo real. . Rescatar tan pronto como una parte del programa sea ambigua es una forma de lograr este objetivo de diseño.

Si prefiere un lenguaje más "tolerante" que intente entender lo que usted quiso decir, VB o JScript podrían ser mejores idiomas para usted. Son más los idiomas "haz lo que quise decir no lo que dije".