2011-05-16 9 views
20

He visto preguntas similares a esto, pero involucran diferentes tipos, así que creo que esta es una pregunta nueva.¿Por qué no se compila "Func <bool> test = value? F: F"?

Considere el siguiente código:

public void Test(bool value) 
{ 
    // The following line provokes a compiler error: 
    // "Type of conditional expression cannot be determined because there is 
    // no implicit conversion between 'method group' and 'method group". 

    Func<bool> test = value ? F : F; 
} 

public bool F() 
{ 
    return false; 
} 

Ahora, de acuerdo con el C# 3.0 Standard,

El segundo y tercer operandos de la :? De mando del tipo de la expresión condicional . Sean X e Y los tipos del segundo y tercer operandos . Entonces,

Si X e Y son del mismo tipo, entonces este es el tipo del condicional lo contrario, si una conversión implícita (apartado 6.1) existe 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 la expresión condicional . De lo contrario, no se puede determinar el tipo de expresión y se produce un error de tiempo de compilación .

Me parece que en mi código de ejemplo, X e Y deben ser del mismo tipo, ya que son la entidad mismo, Func. Entonces, ¿por qué no compila?

+0

no lo sé, pero ¿puede explicar cómo puede escribir un nombre de método con un tipo de retorno nulo como este en una expresión 'Func' ?? –

+0

Lo siento, en mi esfuerzo por simplificar el código de mi código original, eliminé erróneamente el tipo de devolución. ¡Lo arreglé ahora! –

Respuesta

12

La pregunta ha cambiado significativamente, por lo que mi respuesta original está un poco fuera de lugar por ahora.

Sin embargo, el problema es esencialmente el mismo. Es decir. puede haber cualquier número de declaraciones de delegado coincidentes para F y dado que no hay una conversión implícita entre dos declaraciones de delegado idénticas, el tipo de F no se puede convertir a Func<bool>.

Del mismo modo, si se declara

private delegate void X(); 
private delegate void Y(); 
private static void Foo() {} 

no se puede hacer

X x = Foo; 
Y y = x; 

Respuesta original:

No funciona porque los grupos de métodos no se pueden asignar a una forma implícita tipo de variable.

var test = Func; tampoco funciona.

La razón es que podría haber cualquier cantidad de tipos de delegados para Func. P.ej. Func partidos tanto de estas declaraciones (además de Action)

private delegate void X(); 
private delegate void Y(); 

Para utilizar variables implícita de tipo con grupos de métodos, es necesario para eliminar la ambigüedad mediante fundición.


Ver archil's answer para un ejemplo concreto de una manera de solucionar este problema. Es decir, muestra cómo se vería el código corregido [suponiendo que el delegado con el que desea hacer coincidir es Action].

+0

Pero incluso si especifica el tipo de variable de prueba explícitamente como: delegado público void FuncDelegate(); Esta línea aún no funcionará: FuncDelegate funcDelegate = value? Func: Func; ¿Por qué? –

+0

He arreglado mi muestra para que coincida con lo que tenía en mi código original; Lo simplifiqué demasiado cuando lo publiqué aquí la primera vez. –

+0

Cambié mi código para que ya no esté asignando una variable implícitamente tipada. –

8
var test = value ? (Action)Func: (Action)Func; 

En realidad, type del método se expresa por el delegado coincide. System.Action al que utilicé los métodos, el delegado con la firma volviendo vacío y sin tomar ningún parámetro, coincide con el método Func(). Y ahora su test sabrá que es tipo de System.Action. Los delegados son algo así como interfaces para métodos. Eche un vistazo a http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx

+0

Interesante, pero ¿por qué 'valor? (Acción) f: g; 'y' valor? f: (Action) g; 'both compile? –

+0

@MateenUlhaq - Porque cuando le da la * firma * '(Acción) necesaria a cualquiera de las dos, el compilador sabe cuál es el objetivo deseado. Luego puede determinar si la otra mitad se puede convertir a la misma firma. – ToolmakerSteve

Cuestiones relacionadas