?: ?? Operadores en lugar de IF | ELSE

85
public string Source
{
    get
    {
        /*
        if ( Source == null ){
            return string . Empty;
        } else {
            return Source;
        }
        */
        return Source ?? string.Empty;
    }
    set
    {
        /*
        if ( Source == null ) {
            Source = string . Empty;
        } else {
            if ( Source == value ) {
                Source = Source;
            } else {
                Source = value;
            }
        }
        */
        Source == value ? Source : value ?? string.Empty;
        RaisePropertyChanged ( "Source" );
    }
}

¿Puedo usar ?: ??operadores EXACTAMENTE como If / Else?


Mi pregunta:
¿Cómo escribir lo siguiente con?: ?? operadores

[1]

if ( Source == null ){
    // Return Nothing
} else {
    return Source;
}

[2]

if ( Source == value ){
    // Do Nothing
} else {
    Source = value;
    RaisePropertyChanged ( "Source" );
} 

Brevemente : ¿Cómo no hacer nada, no devolver nada y hacer varias instrucciones con el ?: ??operador?

Ahmed Ghoneim
fuente
1
Sin embargo, no se comportará igual. Al no usar la ramificación condicional if / else, está reasignando incondicionalmente (e innecesariamente) la variable cada vez que accede a ella. Eso puede ir mal muy rápidamente, especialmente si tiene un código de subprocesos múltiples. Simplemente no lo hagas.
Jeff Mercado
1
Tendrá una llamada interminable / recursiva si el descriptor de acceso get de la propiedad Source devuelve la propiedad Source (su descriptor de acceso get).
John K
1
Su primer fragmento de código tiene un captador de propiedad que llama a su propio captador , que a su vez llama de forma recursiva a su propio captador . Me perdiste allí, ya que no hay forma de que algo así funcione en el campo. Refina tu pregunta y explica exactamente lo que quieres lograr.
Frédéric Hamidi
Devolver nada? Eso es VB. Estás escribiendo c # aquí.
Tarea
@ Tarea Me refiero a cómo hacerlo, esta línea es un comentario para la pregunta
Ahmed Ghoneim

Respuestas:

198

Para [1], no puede: estos operadores están hechos para devolver un valor, no para realizar operaciones.

La expresion

a ? b : c

evalúa bsi aes verdadero y evalúa csi aes falso.

La expresion

b ?? c

evalúa bsi bno es nulo y evalúa csi bes nulo.

Si tú escribes

return a ? b : c;

o

return b ?? c;

ellos siempre devolver algo.

Para [2], puede escribir una función que devuelva el valor correcto que realice sus "operaciones múltiples", pero probablemente sea peor que simplemente usar if/else.

veracidad
fuente
41

El operador ternario ( ?:) no está diseñado para controlar el flujo , solo está diseñado para una asignación condicional . Si necesita controlar el flujo de su programa, use una estructura de control, como if/ else.

Oliver Charlesworth
fuente
5
Agregaré que he visto a personas usar expresiones ternarias anidadas en lugar de if / else y produce un código que es difícil de leer y depurar. Mal mojo por todas partes.
ckramer
4
A veces, los operadores ternarios anidados producen un código más legible, si los espacios en blanco se utilizan correctamente.
veracidad
2
@truth: Sí, no tengo nada en contra de anidado ?:per se. Pero tengo un gran problema con que se utilicen para el flujo de control, ¡y especialmente el flujo de control anidado !
Oliver Charlesworth
11

Haciendo referencia a ?: Operador (Referencia de C #)

El operador condicional (? :) devuelve uno de dos valores dependiendo del valor de una expresión booleana. A continuación se muestra la sintaxis del operador condicional.

Refiriéndose a ?? Operador (referencia de C #)

Los ?? El operador se denomina operador de fusión nula y se utiliza para definir un valor predeterminado para los tipos de valor que aceptan valores NULL y los tipos de referencia. Devuelve el operando de la izquierda si no es nulo; de lo contrario, devuelve el operando derecho.

Eso significa:

[Parte 1]

return source ?? String.Empty;

[Parte 2] no es aplicable ...

Akram Shahda
fuente
3
Eso es diferente a no hacer nada. Devuelve una cadena vacía.
veracidad
1
Claro, pero eso no es lo que pidió el OP. No es mi culpa que el OP pidiera "no devolver nada", sea lo que sea que eso pueda significar.
Verdad
1
@trutheality: Nadie dijo que es culpa tuya .. Sin embargo, el OP no quería devolver nada y eso es lo que he proporcionado.
Akram Shahda
3

¿El "no hacer nada" realmente no funciona?

si por // Devolver nada, en realidad te refieres a devolver nulo, entonces escribe

return Source;

si quiere decir, ignore la ruta de código y luego escriba

 if ( Source != null )
            {
                return Source;
            }
// source is null so continue on.

Y por ultimo

 if ( Source != value )
            { Source = value;
                RaisePropertyChanged ( "Source" );
            }

// nothing done.
Vinnyq12
fuente
3

El operador ternario DEVUELVE uno de dos valores. O puede ejecutar una de dos declaraciones en función de su condición, pero generalmente no es una buena idea, ya que puede provocar efectos secundarios no deseados.

bar ? () : baz();

En este caso, el () no hace nada, mientras que baz hace algo. Pero solo ha hecho que el código sea menos claro. Yo optaría por un código más detallado, más claro y fácil de mantener.

Además, esto tiene poco sentido en absoluto:

var foo = bar ? () : baz();

ya que () no tiene un tipo de retorno (es nulo) y baz tiene un tipo de retorno que se desconoce en el punto de llamada en este ejemplo. Si no están de acuerdo, el compilador se quejará en voz alta.

Mike Hofer
fuente
2

Si le preocupa la verbosidad de su código, escribiría esto en lugar de intentar abusar de las expresiones.

if (Source == value) return;
Source = value;
RaisePropertyChanged("Source");
ChaosPandion
fuente
No estoy abusando de las expresiones, ¡solo estoy pensando!
Ahmed Ghoneim
1

el?: es el operador del itinerario. (creo que lo escribí correctamente) y es fácil de usar. como en un predicado booleano? iftrue: ifalse; ¿Pero debe tener un rvalue / lvalue como en rvalue = predicate? iftrue: iffalse;

ex int i = x < 7 ? x : 7;

si x fuera menor que 7, me asignarían x, si no, sería 7.

también puede usarlo en una devolución, como en return x < 7 ? x : 7;

de nuevo, como antes, esto tendría el mismo efecto.

Source = Source == value ? Source : string.Empty;Entonces , creo que es lo que estás tratando de lograr.

johnathan
fuente
6
Me gusta. El operador de itinerario : te ayuda a llegar de A a B ... o de A a C ... dependiendo de A.
Rick Sladkey
Sí, se refiere a ternario. Pero el nombre correcto es "condicional".
Erick G. Hagstrom
0

No creo que pueda, es un operador y se supone que debe devolver uno u otro. No es el reemplazo de la declaración if else, aunque se puede usar para eso en ciertos casos.

atbebtg
fuente