visual usar unario ternario operadores operador expresiones ejemplos condicionales como asignacion c# lambda

c# - usar - Asigne una expresión lambda usando el operador condicional(ternario)



operador unario c# (4)

Estoy tratando de usar el operador condicional (ternario) para asignar la expresión lambda adecuada a una variable, dependiendo de una condición, pero recibo el error del compilador: el tipo de expresión condicional no se puede determinar porque no hay una conversión implícita entre la expresión ''lambda ''y'' expresión lambda '' . Puedo usar el if-else regular para resolver este problema, pero el operador condicional tiene más sentido para mí (en este contexto), haría que el código fuera más conciso, al menos, me gustaría saber las razones por las que no lo hace. t trabajo

// this code compiles, but is ugly! :) Action<int> hh; if (1 == 2) hh = (int n) => Console.WriteLine("nope {0}", n); else hh = (int n) => Console.WriteLine("nun {0}", n); // this does not compile Action<int> ff = (1 == 2) ? (int n) => Console.WriteLine("nope {0}", n) : (int n) => Console.WriteLine("nun {0}", n);


Básicamente la misma respuesta que los demás, en una forma diferente.

Action<int> ff = (1 == 2) ? new Action<int>(n => Console.WriteLine("nope {0}", n)) : new Action<int>(n => Console.WriteLine("nun {0}", n));


De hecho, con la inferencia de tipos, puede:

  • Usa var para la variable local
  • Solo emitir la primera expresión del operador ternario.
  • Omita el tipo del parámetro lambda ya que puede inferirse

El resultado es mucho más conciso. (Te dejo decidir si es más legible.)

var ff = condition ? (Action<int>)(n => Console.WriteLine("nope {0}", n)) : n => Console.WriteLine("nun {0}", n);


El compilador de C # intenta crear las lambdas de forma independiente y no puede determinar el tipo de forma inequívoca. Casting puede informar al compilador qué tipo usar:

Action<int> ff = (1 == 2) ? (Action<int>)((int n) => Console.WriteLine("nope {0}", n)) : (Action<int>)((int n) => Console.WriteLine("nun {0}", n));


Esto funcionará.

Action<int> ff = (1 == 2) ? (Action<int>)((int n) => Console.WriteLine("nope {0}", n)) : (Action<int>)((int n) => Console.WriteLine("nun {0}", n));

Hay dos problemas aquí

  1. Expresión
  2. Operador ternario

1. Problema con la expresión

El compilador le está diciendo exactamente qué es incorrecto: ''Type of conditional expression cannot be determined because there is no implicit conversion between ''lambda expression'' and ''lambda expression'' .

Significa que lo que ha escrito es la expresión lambda y la variable resultante también es la expresión lambda.

La expresión lambda no tiene ningún tipo en particular, solo se puede convertir al árbol de expresiones.

Una expresión de acceso de miembro (que es lo que intentas hacer) solo está disponible en los formularios

primary-expression . identifier type-argument-list(opt) predefined-type . identifier type-argument-list(opt) qualified-alias-member . identifier type-argument-list(opt)

... y una expresión lambda no es una expresión primaria.

2. Problema con el operador ternario

Si lo hacemos

bool? br = (1 == 2) ? true: null;

Esto resulta en un error que dice exactamente igual que el tuyo. ''Type of conditional expression cannot be determined because there is no implicit conversion between ''bool'' and ''<null>''

Pero el error desaparece si hacemos esto.

bool? br = (1 == 2) ? (bool?)true: (bool?)null;

Casting de un lado también funcionará

bool? br = (1 == 2) ? (bool?)true: null;

O

bool? br = (1 == 2) ? true: (bool?)null;

Para tu caso

Action<int> ff = (1 == 2) ? (Action<int>)((int n) => Console.WriteLine("nope {0}", n)) : ((int n) => Console.WriteLine("nun {0}", n));

O

Action<int> ff = (1 == 2) ? ((int n) => Console.WriteLine("nope {0}", n)) : (Action<int>)((int n) => Console.WriteLine("nun {0}", n));