El compilador de C# requiere que cada vez que un tipo personalizado define operador ==, debe también definir != (ver aquí).

¿Por qué?

Tengo la curiosidad de saber por qué los diseñadores de pensamiento que es necesario y por qué no puede el compilador por defecto para una razonable aplicación de cualquiera de los operadores sólo cuando el otro está presente. Por ejemplo, Lua permite definir sólo el operador de igualdad y de obtener otra gratuitamente. C# podría hacer lo mismo, pidiendo que se defina == o ambos, = = y != y luego recopilar de forma automática la falta != operador !(left == right).

Yo entiendo que no es extraño esquina casos en los que algunas entidades no podrá ser igual ni desigual, (como IEEE-754 de NaN), pero los que parecen como la excepción, no la regla. Así que esto no explica por qué el compilador de C# de los diseñadores de hecho la excepción de la regla.

He visto casos de escasa mano de obra, donde el operador de igualdad se define, entonces el operador de desigualdad es un copiar-pegar con todas y cada una comparación invertido y cada una de las && pasó a un || (usted consigue el punto… básicamente !(a==b) se expandió a través de De Morgan de las reglas). Eso es una mala práctica que el compilador podría eliminar por diseño, como es el caso de la Lua.

Nota:
Lo mismo vale para los operadores < > <= >=. No me puedo imaginar casos en los que usted necesita para definir estos de forma poco natural. Lua permite definir sólo < y <= y define >= y > naturalmente a través de los formadores de’ negación. ¿Por qué no C# hacer lo mismo (al menos ‘por defecto’)?

EDITAR

Al parecer hay razones válidas para permitir que el programador para implementar controles para la igualdad y la desigualdad, sin embargo les gusta. Algunas de las respuestas apuntan a los casos en los que puede ser agradable.

El núcleo de mi pregunta, sin embargo, es por eso que esta es la fuerza requerida en C# cuando generalmente no lógicamente necesario?

Es también en contraste con las opciones de diseño para .NET interfaces como Object.Equals, IEquatable.Equals IEqualityComparer.Equals donde la falta de un NotEquals contraparte muestra que el marco considera !Equals() objetos como la desigualdad y punto. Además, las clases como Dictionary y métodos como .Contains() dependen exclusivamente de la mencionada interfaces y no utilizar los operadores directamente, incluso si están definidos. De hecho, cuando ReSharper genera igualdad de los miembros, se define tanto == y != en términos de Equals() y aún entonces, sólo si el usuario elige para generar los operadores en todo. Los operadores de igualdad no son necesarios por el marco de referencia para entender el objeto de la igualdad.

Básicamente, la .NET framework no se preocupa de estos operadores, que sólo se preocupa por un par de Equals métodos. La decisión de exigir tanto a == y != los operadores definidos en tándem por el usuario es puramente relacionadas con el diseño del lenguaje y no objeto de la semántica tan lejos como .NETO se refiere.

  • +1 para una excelente pregunta. No parece haber ninguna razón en todo… por supuesto, el compilador podría suponer que una != b puede ser traducida.(a == b) a menos que se indique lo contrario. Tengo la curiosidad de saber por qué se decidió a hacer esto, también.
  • Este es el más rápido que he visto una pregunta votado y favoritos.
  • Estoy seguro de que @Eric Lippert puede proporcionar un sonido de respuesta así.
  • Currens: puedo decir lo mismo acerca de tu comentario 😉
  • «El científico no es una persona que da las respuestas correctas, él es quien hace las preguntas correctas». Esta es la razón por la SE, las preguntas son bienvenidas. Y funciona!
  • Que algo de lo que no dicen los científicos!
  • ¿Usted piensa que yo no sé? Sólo quería spice it up!
  • Si es tan sencillo como !(left == right), no es un problema para usted. Si la negación es mucho más complicado, el compilador no tiene la oportunidad de optimizar – pero. Por lo tanto, es consecuencia de la fuerza para controlar ambos casos por ti mismo.
  • El #1 cajón de sastre regla de oro de diseño de software, APIs, y GUIs es: Siempre hacer el común de los casos el valor por defecto. Se parece a alguien equivocadamente no hizo eso.
  • Personalmente estoy prefiriendo un compilador que no pensar demasiado las cosas por sí mismo, de lo contrario corro el riesgo de olvidar a pensar por mí mismo, cuando el compilador se equivoca.
  • Hasta que Eric o Jon rodar a través de un devastadoramente razón convincente, demostrando todos mal como parece suceder mucho por aquí.
  • Creo que sólo la gente que diseñó C# puede responder a esta correctamente, otra cosa es bastante sólo una suposición. De hecho, yo ni siquiera estar seguro de que no hay una respuesta satisfactoria.
  • La misma pregunta para Python: stackoverflow.com/questions/4969629/…
  • la regla de oro de diseño de software, APIs, y GUIs no es necesariamente la regla de oro de que el compilador de diseño. Compilador de la prioridad debe ser evitar errores de tiempo de ejecución, en caso de duda, en el costo de programador de conveniencia.
  • En realidad es de sentido común que != debe ser lo contrario de lo que sea == se implementa como ahora? A mí me parece como mucho de sentido común suponer que la implementación predeterminada de != debe ser el opuesto de la implementación predeterminada de ==, a menos que reemplaza. Quizás el sentido común, en este caso, realmente no es de sentido común a todos?
  • Tal vez fue sólo precaución. Si usted comienza con ‘los operadores deben venir en pares’, usted tiene la capacidad de cambiar a inferir omitido operador de los socios. Usted no puede ir en la otra dirección.
  • Fantástico pregunta! Es a preguntas como estas, y la participación masiva, que muestran realmente cuán grandes de una comunidad de Stackoverflow es! Y dónde está @Joh Skeet? Me encantaría ver su respuesta!

13 Comentarios

  1. 158

    No puedo hablar por el lenguaje de los diseñadores, pero de lo que puedo razón, parece que no fue intencional, la correcta decisión de diseño.

    Mirando este básica F# código, usted puede compilar en un trabajo de la biblioteca. Este es el código legal de F#, y sólo se sobrecarga el operador de igualdad, no la desigualdad:

    module Module1
    
    type Foo() =
        let mutable myInternalValue = 0
        member this.Prop
            with get () = myInternalValue
            and set (value) = myInternalValue <- value
    
        static member op_Equality (left : Foo, right : Foo) = left.Prop = right.Prop
        //static member op_Inequality (left : Foo, right : Foo) = left.Prop <> right.Prop

    Esto es exactamente lo que parece. Crea un comparador de igualdad en == sólo, y comprueba si los valores internos de la clase son iguales.

    Mientras que no se puede crear una clase como esta en C#, puede uso uno que fue compilado por .NET. Es obvio que va a utilizar nuestro operador sobrecargado para == Así que, ¿qué hace el tiempo de ejecución de utilizar para !=?

    El C# EMCA estándar tiene un montón de reglas (sección 14.9) que explica cómo determinar qué operador al momento de evaluar la igualdad. Para ponerlo excesivamente simplificada y, por tanto, no exacta, si los tipos que se comparan son del mismo tipo y hay una sobrecarga del operador de igualdad presente, el uso que se sobrecarga y no de la norma de referencia del operador de igualdad heredado de Object. No es de extrañar, entonces, que si sólo uno de los operadores está presente, se utilizará el valor predeterminado de referencia del operador de igualdad, de que todos los objetos tienen, no hay una sobrecarga para ella.1

    Sabiendo que este es el caso, la pregunta real es: ¿por Qué fue esta diseñado de esta manera y por qué no el compilador de la figura hacia fuera en sus el propios? Mucha gente está diciendo que esto no era una decisión de diseño, pero me gusta pensar que fue pensado de esta manera, especialmente en relación con el hecho de que todos los objetos tienen un defecto operador de igualdad.

    Así que, ¿por qué no el compilador automáticamente crear el != operador? No puedo saber con certeza a menos que alguien de Microsoft confirma esto, pero esto es lo que puede determinar a partir de razonamiento sobre los hechos.


    Para evitar un comportamiento inesperado

    Tal vez quiero hacer una comparación de valor en == para probar la igualdad. Sin embargo, cuando llegó a != no me importaba en absoluto si los valores son iguales, a menos que la referencia era igual, porque para mi programa de considerar la igualdad, sólo me importa si coincide con las referencias. Después de todo, este es descrito como comportamiento predeterminado de la C# (si ambos operadores no estaban sobrecargados, como sería en el caso de algunos .red de bibliotecas escritas en otro idioma). Si el compilador fue la incorporación en el código automáticamente, yo ya no podía confiar en que el compilador de código de salida que debe es compatible. El compilador no debe escribir código oculto que cambia el comportamiento de los suyos, especialmente cuando el código que has escrito está dentro de los estándares de C# y de la CLI.

    En términos de que obligando a a la sobrecarga de que, en lugar de ir al comportamiento por defecto, sólo puedo firmemente decir que es en el estándar (EMCA-334 17.9.2)2. El estándar no especifica por qué. Creo que esto es debido al hecho de que C# prestado la mayor parte del comportamiento de C++. Ver abajo para más información sobre esto.


    Cuando se reemplaza != y ==, usted no tiene que devolver bool.

    Esta es otra razón más probable. En C#, esta función:

    public static int operator ==(MyClass a, MyClass b) { return 0; }

    es tan válida como esta:

    public static bool operator ==(MyClass a, MyClass b) { return true; }

    Si usted está devolviendo algo distinto de bool, el compilador no automáticamente inferir un tipo opuesto. Además, en el caso de que el operador hace return bool, que simplemente no tiene sentido para ellos crear generar código que sólo existen en un caso concreto o, como he dicho anteriormente, el código que oculta el comportamiento predeterminado de la CLR.


    C# toma prestado mucho de C++3

    Cuando C# se introdujo, se publicó un artículo en la revista MSDN magazine que escribió, hablando de C#:

    Muchos desarrolladores gustaría que existiera un lenguaje que sea fácil de escribir, leer y mantener, como Visual Basic, pero que sigue siendo la potencia y la flexibilidad de C++.

    Sí, el objetivo de diseño para C# fue a dar casi la misma cantidad de energía como C++, que sacrifica un poco de la ventaja de tipo rígido-seguridad y recolección de basura. C# fue fuertemente modelada después de C++.

    No puede ser sorprendido al enterarse de que en C++, el operadores de igualdad de no tener que volver bool, como se muestra en la este programa de ejemplo

    Ahora, C++ no directamente requieren a la sobrecarga de la complementaria operador. Si su compilado el código en el programa de ejemplo, verá que se ejecuta sin errores. Sin embargo, si se trató de añadir la línea:

    cout << (a != b);

    obtendrá

    de error del compilador C2678 (MSVC) : binario ‘!=’ : no hay ningún operador que toma a la izquierda el operando de tipo ‘Test’ (o no es aceptable conversión)`.

    Así, mientras que C++ no requiere que la sobrecarga en pares, no permiten utilizar un operador de igualdad que aún no sobrecargar en una clase personalizada. Es válido en .NETA, ya que todos los objetos tienen un valor predeterminado; C++ no.


    1. Como una nota del lado, el C# estándar debe a una sobrecarga del par de operadores si desea sobrecarga de cualquiera de los dos. Esta es una parte de la estándar y no simplemente la compilador. Sin embargo, las mismas reglas con respecto a la determinación de que el operador de llamar a aplicar cuando se está accediendo a una .neto de la biblioteca escrita en otro idioma que no tienen los mismos requerimientos.

    2. EMCA-334 (pdf) (http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf)

    3. Y Java, pero que realmente no es el punto aquí

    • «usted no tiene que devolver bool» .. creo que nuestra respuesta en ese momento; bien hecho. Si!!!(o1 == o2) no está aún bien definido, entonces usted no puede esperar que el estándar a confiar en ella.
    • Irónicamente, en un tema sobre los operadores lógicos se han utilizado una doble negativa en la frase, «C# no permite no reemplazar sólo uno de los dos», que en realidad lógicamente significa «C# no permite reemplazar sólo uno de los dos».
    • Diplo, Es bueno, no Es como si no estuviera prohibido no hacer eso o no.
    • Creo que su primera citada sentencia lógicamente significa «C# requiere [no sólo permite a] a reemplazar sólo uno de los dos».
    • Si es verdad, sospecho #2 es correcta; pero ahora, la pregunta es, ¿por qué permitir que == a devolver nada, pero un bool? Si devuelve un int, ya no se puede utilizar como un enunciado condicional, por ejemplo. if(a == b) ya no se compilará. ¿Cuál es el punto?
    • Usted puede devolver un objeto que tiene una conversión implícita a bool (operador de verdadero/falso), pero sigo sin ver en que sería útil.
    • usted puede devolver algo que no sea bool si desea implementar algunos no la lógica booleana. Por ejemplo, en algunos de lógica difusa de los casos, usted no sabe con certeza si un valor es igual a la otra, así que usted puede devolver el probabilidad de un valor equivalente al de los otros (un doble valor entre 0 y 1).
    • pero, ¿no se puede utilizar un método con un nombre descriptivo para ese propósito, en lugar de un operador que puede sembrar la confusión?
    • Ah, te refieres a que una mala elección llevó a la otra. La primera mala elección es tener predicados que no devuelven un valor booleano. Lo que conduce a la mala elección que debemos reemplazar ambos == y !=.
    • Iba a escribir la lógica difusa código utilizando == y !=? Si no, ¿de verdad infligir ese código en alguien más? 🙂 En lugar creo que sería más claro (y también más C# estilo vs C++) para proporcionar el nombre de un miembro como Truthiness().
    • Stefan, yo no escribiría que yo (no me gusta sobrecarga de operadores en general, incluso para las clases donde es normalmente aceptado, como los números Complejos), pero no veo una razón por qué la gente no debería ser capaz de expresar su lógica en una forma «natural» (es decir, el uso de los operadores), si su sistema está basado en él (por lo que la confusión de los operadores sería disminuida).
    • H – Dudoso que fue una mala elección. La decisión se basa en el mismo en C++. No sólo puede el operator== devolver lo que usted quiere, usted está obligado a la sobrecarga de la operator!= si intenta utilizarlo y no lo ha hecho ya. Estamos hablando de los idiomas que se supone que dan tanta libertad como sea posible aquí.
    • Justo lo suficiente. Tal vez he malinterpretado el espíritu de C# en contraste a la de C++, y por qué alguien quiere utilizar el uno o el otro.
    • H, como un ejemplo de caso de uso, teniendo == o != devolver algo distinto booleano permite infecciosas de error de los resultados. E. g. en IEE754, 0.0 / 0.0 es un especial NaN valor que infecta a todos los operadores aritméticos; NaN + anyValue es NaN y lo mismo para -, *, y /. Pero que el bit de error a menudo se pierde involuntariamente cuando los valores de comparación. Con este tipo de sobrecarga puede hacer el mismo tipo de infecciosas valor de error para los operadores lógicos.

  2. 50

    Probablemente, por si alguien necesita implementar tres valores de la lógica (es decir,null). En casos como el que – estándar ANSI SQL, por ejemplo -, los operadores no pueden simplemente ser negados en función de la entrada.

    Usted podría tener un caso en donde:

    var a = SomeObject();

    Y a == true devuelve false y a == false también devuelve false.

    • Yo diría que en ese caso, ya que a no es un valor booleano que se debe comparar con un tres-estado de enumeración, no es un verdadero true o false.
    • Gordon: Probablemente la correcta. Mi ejemplo es tal vez un poco artificial, pero el razonamiento detrás de esto todavía tiene creo. Hay casos en los que usted no querría != a ser definidos de forma automática (y inmutablemente) como la lógica opuesta de ==.
    • Buena comparación con SQL.
    • Pero en ese caso, ¿por qué no el usuario a definir lo que entendemos por «!=»? En la mayoría, una respuesta razonable en este caso sería emitir una advertencia si la compilación es pedante.
    • Por cierto, no puedo creer que a nadie se hace referencia a la FileNotFound broma..
    • Si a == true es false entonces yo siempre iba a esperar a != true a ser true, a pesar de a == false ser false
    • Gordon Esta no es la DailyWTF 🙂
    • si a == true es false luego a no true. No estamos hablando acerca de las referencias aquí (===), solo binario de los estados.
    • golpear el clavo en la cabeza. Esto realmente no tiene nada que ver con la pregunta – usted está explicando por qué alguien podría querer reemplazar ==, no es por eso que debe ser forzado a reemplazar ambos.
    • No puedo pensar en ningún caso práctico en el que un != y == no dan resultados opuestos.
    • Danny Pflughoeft: El OP es la pregunta de por qué el compilador no puede predeterminado a una «razonable la aplicación». Mi respuesta es que no siempre es evidente qué es un «razonable aplicación» podría ser.
    • Sí, hay una buena implementación predeterminada: es el caso común. Incluso en tu ejemplo, la implementación predeterminada de != sería correcto. En el muy infrecuente caso de que nos gustaría x == y y x != y a ser false (no puedo pensar en un ejemplo único que tiene sentido), que todavía podría reemplazar el valor predeterminado de aplicación y proporcionan su propio. Siempre hacer el común de los casos el valor por defecto.
    • Un buen ejemplo de esto.

  3. 24

    Otro que el de C# difiere a la de C++ en muchas áreas, la mejor explicación que se me ocurre es que en algunos casos es posible que desee tomar un ligeramente enfoque diferente para probar «no igualdad» que para acreditar la «igualdad».

    Obviamente con la comparación de cadenas, por ejemplo, usted puede comprobar la igualdad y return fuera del bucle cuando vea no coincidentes caracteres. Sin embargo, podría no ser tan limpia con problemas más complicados. El bloom filter viene a la mente; es muy fácil saber rápidamente si el elemento es no en el conjunto, pero es difícil decir si el elemento es en el conjunto. Mientras que el mismo return técnica podría ser de aplicación, el código podría no ser tan bonita.

    • Gran ejemplo; creo que está en la razón. Un simple ! la encierra en una sola definición para la igualdad, donde una informado programador podría ser capaz de optimizar tanto == y !=.
    • Esto explica por qué se les debe dar la opción para anular tanto, no es por eso que debe ser obligados.
    • En ese sentido, ellos no tienen que optimizar tanto, sólo tienen que proporcionar una definición clara de ambos.
  4. 20

    Si usted mira en las implementaciones de sobrecargas == y != en el .fuente neta, que a menudo no implementar != como !(=izquierda= derecha). Aplicarlo plenamente (como ==) con lógica negada. Por ejemplo, DateTime implementa == como

    return d1.InternalTicks == d2.InternalTicks;

    y != como

    return d1.InternalTicks != d2.InternalTicks;

    Si usted (o que el compilador si lo hizo de manera implícita) fueron a implementar != como

    return !(d1==d2);

    continuación, usted está haciendo una suposición acerca de la implementación interna de == y != en las cosas de su clase de referencia. Evitar la suposición de que puede ser la filosofía detrás de su decisión.

  5. 16

    Para responder a su edición, con respecto a por qué se ve obligado a reemplazar tanto si reemplazar a uno, todo en la herencia.

    Si reemplazar ==, más probabilidades de proporcionar algún tipo de semántica estructural o de igualdad (por ejemplo, DateTimes son iguales si sus InternalTicks propiedades son iguales, incluso a través de ellos pueden ser diferentes instancias), entonces va a cambiar el comportamiento predeterminado del operador de Objeto, que es el padre de todos .NETO de los objetos. El operador == es decir, en C#, un método, cuya base la implementación del Objeto.operador(==) realiza un referencial de comparación. Objeto.operador(!=) es un método diferente, que también realiza una comparación referencial.

    En casi cualquier otro caso de método de sustitución, sería ilógico suponer que reemplazar un método que también se traduciría en un cambio de comportamiento a un antonymic método. Si ha creado una clase con Increment() y Decremento() los métodos, y pasó por encima de Incremento() en un niño de la clase, se puede esperar Decrementar() también se puede reemplazarse con la opuesta de su reemplaza el comportamiento? El compilador no puede hacerse lo suficientemente inteligente como para generar una función inversa para la implementación de un operador en todos los casos posibles.

    Sin embargo, los operadores, aunque aplicado de manera muy similar a los métodos, conceptualmente, el trabajo en parejas, = = y !=, < y > y <= y >=. Sería ilógico en este caso desde el punto de vista de un consumidor a pensar que != trabajó diferente que a ==. Así, el compilador no puede ser hecho de asumir que un!=b == !(a==b) en todos los casos, pero en general se espera que == y != debe funcionar de una manera similar, por lo que el compilador obliga a implementar en pares, sin embargo, que en realidad terminan haciendo eso. Si, por su clase, a!=b == !(a==b), entonces basta con poner en práctica el != operador de usar !(==), pero si que la regla no se sostiene en todos los casos para el objeto (por ejemplo, si la comparación con un determinado valor, igual o desigual, no es válido), entonces usted tiene que ser más inteligente que el IDE.

    La VERDADERA pregunta que debe ser respondida es ¿por < y > y <= y >= son pares para la comparativa de los operadores, que deben ser implementadas de forma concurrente, cuando en términos numéricos !(a < b) == a >= b y !(a >, b) == a <= b. Usted debe exigir que se apliquen los cuatro si reemplazar a uno, y probablemente debería ser necesario reemplazar == (y !=) así, debido a que (a <= b) == (a == b) si a es semánticamente equivalente a b.

    • +1 para antonymic! Muy lógico y razonamiento claro.
    • +1, pero usted mixto hasta el último operador en !(a < b) == a >= b and !(a > b) == a >= b
  6. 13

    Si sobrecarga == para el tipo personalizado, y no != entonces será manejado por el != operador de objeto != objeto, ya que todo se deriva de object, y esto sería muy diferente de CustomType != CustomType.

    También el lenguaje de los creadores probablemente quería de esta manera para permitir que la mayoría de los más flexibilidad para los codificadores, y también por lo que no están haciendo suposiciones acerca de lo que usted piensa hacer.

    • Inspirado esta pregunta: stackoverflow.com/questions/6919259/…
    • La flexibilidad de la razón también puede ser aplicado a un gran número de características que decidieron dejar de lado, por ejemplo blogs.msdn.com/b/ericlippert/archive/2011/06/23/… .Por lo tanto no explica su elección, para la aplicación de operadores de igualdad.
    • Que es muy interesante. Parece que parece que sería una característica útil. No tengo idea de por qué se ha dejado que uno.
  7. 9

    Esto es lo que viene a mi mente primero:

    • Lo que si pruebas de la desigualdad es mucho más rápido que las pruebas de la igualdad?
    • Lo que si en algunos casos desea volver false tanto para == y != (es decir, si no puede ser comparado por alguna razón)
    • En el primer caso se podría implementar la igualdad de las pruebas en términos de la desigualdad de las pruebas.
    • El segundo caso se va a romper estructuras como Dictionary y List si utiliza el tipo personalizado con ellos.
    • utiliza GetHashCode y Equals, no los operadores. List utiliza Equals.
  8. 5

    Bien, probablemente se trate de una opción de diseño, pero como dices, x!= y no tiene que ser el mismo que !(x == y). Por no añadir una implementación predeterminada, usted está seguro de que usted no puede olvidar a implementar una aplicación específica. Y si es tan trivial como usted dice, usted puede implementar uno con el otro. No veo cómo esto es ‘mala práctica’.

    Puede haber algunas otras diferencias entre C# y Lua demasiado…

    • Es una excelente práctica de la aplicación de uno en términos del otro. Acabo de ver que se haga de otra manera – que es propensa a errores.
    • Ese es el problema de que el programador, no en C#’s problema. Los programadores que incumplan con la implementación de este derecho, se producirá en otras áreas también.
    • Podría usted explicar que Lua de referencia? No estoy del todo familiarizado con Lua, pero la referencia parece insinuar algo.
    • Wei: OP señala que Lua hace esto de manera diferente de C# (Lua al parecer hace add default homólogos de los citados operadores). Tratando de trivializar una comparación de ese tipo. Si no hay diferencias, entonces al menos uno de ellos no tiene derecho a existir. Debe decir no sé Lua bien.
  9. 5

    De las palabras clave en tu pregunta son «por qué» y «debe«.

    Como resultado:

    Responder es de esta manera porque se diseñó para ser así, es cierto … pero no contestar el «por qué» parte de su pregunta.

    Responder que podría ser útil a veces para anular el tanto de estos de forma independiente, es cierto … pero no contestar el «debe» en parte de su pregunta.

    Creo que la respuesta simple es que no no ninguna razón convincente de por qué C# requiere a reemplazar ambos.

    El lenguaje debe permitir que usted para reemplazar sólo ==, y proporcionar una implementación predeterminada de != que es ! que. Si por casualidad usted desea anular != así, tener en ella.

    No fue una buena decisión. Los seres humanos lenguajes de diseño, los seres humanos no son perfectos, C# no es perfecto. Encogimiento de hombros y Q. E. D.

  10. 4

    Sólo para añadir a la excelente respuesta aquí:

    Considerar lo que iba a suceder en el depurador, cuando intenta entrar en un != operador y terminan en un == operador lugar! Hablar confuso!

    Tiene sentido que el CLR permitiría la libertad de dejar fuera a uno u otro de los operadores – como debe de trabajar con muchos idiomas. Pero hay un montón de ejemplos de C# no exponer CLR características (ref devuelve y locales, por ejemplo), y un montón de ejemplos de la aplicación de las características no en el CLR en sí (por ejemplo: using, lock, foreach, etc).

  11. 2

    De los lenguajes de programación son sintácticos reordenamientos de excepcionalmente compleja instrucción lógica. Con eso en mente, se puede definir un caso de igualdad, sin la definición de un caso de falta de igualdad? La respuesta es no. Para que un objeto sea igual al objeto b, entonces la inversa de objeto a no es igual a b, también debe ser cierto. Otra manera de mostrar esto es

    if a == b then !(a != b)

    esto proporciona cierta capacidad para el lenguaje para determinar la igualdad de los objetos. Por ejemplo, la comparación NULL != NULL puede lanzar una llave inglesa en la definición de un sistema de igualdad que no implementa un no-igualdad de instrucción.

    Ahora, en lo que respecta a la idea de != simplemente ser reemplazable definición como en

    if !(a==b) then a!=b

    No puedo discutir con eso. Sin embargo, seguramente se trataba de una decisión por parte de la especificación del lenguaje C# de grupo que el programador se ven obligados a definir explícitamente la igualdad y la no-igualdad de un objeto junto

    • Null sólo sería un problema porque null es una entrada válida para ==, que no debería ser, aunque obviamente, es masivamente conveniente. Personalmente, yo creo que es simplemente permite que grandes cantidades de vago, descuidado de programación.
  12. 2

    En resumen, obligó a la consistencia.

    ‘==’ y ‘!=’ son siempre verdaderos opuestos, no importa cómo se definen ellos, que se define como tal por sus verbal definición de «iguales» y «no es igual.» Sólo por la definición de uno de ellos, se abre a un operador de igualdad inconsistencia donde ambos ‘==’ y ‘!=’ pueden ser ambas verdaderas o ambas sean falsas para dos valores dados. Debe definir tanto desde cuando usted elige para definir uno, también debe definir el otro adecuada, de modo que es descaradamente claro cuál es su definición de «igualdad» es. La otra solución para el compilador es sólo permiten reemplazar ‘==’ O ‘!=’ y dejar la otra como inherentemente la negación de la otra. Obviamente, ese no es el caso con el compilador de C# y estoy seguro de que hay una razón válida para que que puede ser atribuible estrictamente como una opción de la simplicidad.

    La pregunta que debemos hacernos es «¿por qué tengo que reemplazar los operadores?» Que es una firme decisión para hacer lo que requiere una gran razonamiento. Para los objetos, ‘==’ y ‘!=’ comparar por referencia. Si va a reemplazar a NO comparar por referencia, se está creando un operador general de la incoherencia de que no es evidente para cualquier otro desarrollador que iba a leer ese código. Si usted está tratando de hacer la pregunta «es el estado de estas dos instancias equivalentes?,» entonces usted debe implementar IEquatible, definir Equals() y utilizar esa llamada al método.

    Por último, IEquatable() no define NotEquals() para el mismo razonamiento: el potencial para abrir operador de igualdad inconsistencias. NotEquals() debe devolver SIEMPRE !Equals(). Por la apertura de la definición de NotEquals() de la clase a la implementación de Equals(), una vez más, obligando a la cuestión de la coherencia en la determinación de la igualdad.

    Edit: Esto es simplemente mi razonamiento.

    • Esto es ilógico. Si el motivo de la consistencia, a continuación, lo contrario sería aplicar: usted sólo sería capaz de implementar operator == y el compilador podría inferir operator !=. Después de todo, esto es lo que hace para operator + y operator +=.
    • foo += bar; es un compuesto de asignación, la abreviatura de foo = foo + barra;. No es un operador.
  13. -2

    Probablemente sólo algo que no creo que de no tener tiempo para hacerlo.

    Yo siempre uso su método cuando yo sobrecarga ==. A continuación, sólo tiene que utilizar en el otro.

    Tienes razón, con una pequeña cantidad de trabajo, el compilador podría dar esto a nosotros de forma gratuita.

Dejar respuesta

Please enter your comment!
Please enter your name here