2008-10-20 12 views
29

Tengo curiosidad de por qué una conversión implícita falla en ...En C# ¿Por qué no puede un operador condicional implícita echado a un tipo anulable

int? someValue = SomeCondition ? ResultOfSomeCalc() : null; 

y por qué tengo que realizar una conversión explícita en lugar

int? someValue = SomeCondition ? ResultofSomeCalc() : (int?)null; 

Me parece que el compilador tiene toda la información que necesita para tomar una decisión implícita de lanzamiento, ¿no?

+5

No editaré su título yo mismo, pero sugiero que cambie la palabra terrnary a condicional: el operador se llama operador condicional. Es * a * operador ternario, y actualmente el único, pero eso no describe nada más que el número de operandos. –

+3

Tal vez soy más descarado, pero lo haré ... –

+0

@MarcGravell Soy descarado y espero que sea correcto, ¿no debería el título ser '** el ** operador condicional"? :) –

Respuesta

27

La sección pertinente de la especificación C# 3.0 es 7,13, el operador condicional:

El segundo y tercer operandos de la:? Control del operador el tipo de la expresión condicional. Deje que X e Y sean los tipos del segundo y tercer operandos. Luego,

Si X e Y son del mismo tipo, este es el tipo del condicional . De lo contrario, si existe una conversión implícita (§6.1) de X a Y, pero no de Y a X, entonces Y es el tipo de la expresión condicional. De lo contrario, si existe una conversión implícita (§6.1) de Y a X, pero no de X a Y, entonces X es el tipo de expresión condicional. De lo contrario, no se puede determinar ningún tipo de expresión y se produce un error en tiempo de compilación.

+6

En resumen, no tiene en cuenta a qué tipo se está asignando en el resultado de la operación. Simplemente trata de descubrir el lado derecho del tipo de ecuación, ignorando los tipos Nullable. – TheSoftwareJedi

+0

Pero consideremos el caso del encadenamiento ternario. ¿De qué otra forma lo sabría? –

+0

@DJ Floetic: ¿comenzaría en el operador 'innermost'?: Averiguará el tipo de resultado y luego saldrá. –

14

También me molesta que no se puede inferir el tipo en función de la asignación, especialmente cuando se trata de un tipo de valor. Sin embargo, hay razones cuando te metes en jerarquías de objetos.

Si "ResultOfSomeCalc()" devolvió un "int?", Entonces esto funcionaría. C# necesita averiguar el tipo independientemente de lo que esté a la izquierda de la tarea. Entonces le está diciendo que devolverá un nulo o un int. Y la lógica en el compilador no existe para que sustituya un Nullable como un denominador común.

en cuenta que estas variantes hacer el trabajo, y que pueden ayudarle a entender:

object someValue = true ? new Nullable<int>(ResultOfSomeCalc()) : null; 

object someValue = true ? (int?)ResultOfSomeCalc() : null; 

Espero que esto ayude.

+0

También una muy buena respuesta, acepté DJ's y voté como tuyo. –

0

Si su función ResultofSomeCalc() devuelve int? entonces esto funcionará

Si su función devuelve int, entonces el compilador emite la advertencia: Tipo de expresión condicional no se puede determinar porque no hay una conversión implícita entre 'int' y ''
supongo que es lo que está viendo . Ambas expresiones en el operador condicional "?:" Deben tener el mismo tipo, o deben ser convertibles al mismo tipo a través de un molde implícito.

¿Cambiar el tipo de devolución de ResultOfSomeCalc a int ?, o tendrá que tener el molde en la expresión nula.

5

Parece que esto es algo que el compilador debería poder descifrar por sí mismo, pero hay otra forma de hacerlo, utilizando la palabra clave predeterminada. Puede ser que sea los más pequeños poco menos feo que el reparto:

int? someValue = SomeCondition ? ResultofSomeCalc() : default(int?); 

Este uso del defecto no parece estar bien documentado, pero es que funciona.Al menos te evita tener que ensuciar tu código con valores mágicos (sostengo que null/zero/false/etc. Son de hecho valores mágicos).

0

Realice su función Tipo de devolución de ResultOfSomeCalc() como nullabel int como (int?)
int? someValue = (int?) SomeCondition? ResultofSomeCalc(): (int?) Null;

Cuestiones relacionadas