2012-03-21 8 views
5

Estoy intentando crear una expresión ternaria y estoy consiguiendo el error siguienteExpresión ternario con interfaces como clase base

"Tipo de expresión condicional no se puede determinar porque no hay una conversión implícita entre LiveSubscription y DisconnectedSubscription"

la misma lógica funciona en una sentencia if, pero quería entender por qué no va a funcionar en una expresión ternaria -

Esta es la esencia de lo que estoy tratando de hacer:

public interface IClientSubscription 
{ 
    bool TryDisconnect(); 
} 

public class LiveSubscription : IClientSubscription 
{ 
    public bool TryDisconnect() 
    { 
     return true; 
    } 
} 

public class DisconnectedSubscription : IClientSubscription 
{ 
    public bool TryDisconnect() 
    { 
     return true; 
    } 
} 

public class ConnectionManager 
{ 
    public readonly IClientSubscription Subscription; 

    public ConnectionManager(bool IsLive) 
    { 
     // This throws the exception 
     Subscription = (IsLive) 
      ? new LiveSubscription() 
      : new DisconnectedSubscription(); 

     // This works 
     if (IsLive) 
     { 
      Subscription = new LiveSubscription(); 
     } 
     else 
     { 
      Subscription = new DisconnectedSubscription(); 
     } 
    } 
} 

Siempre pude cambiarlo a un if/else pero primero quería entender qué está mal.

Respuesta

8

, es necesario especificar al menos uno de los operandos a IClientSubscription:

Subscription = (IsLive) 
      ? (IClientSubscription)new LiveSubscription() 
      : new DisconnectedSubscription(); 

La razón es que la expresión ternaria es de un cierto tipo que está determinada por los operandos. Básicamente, intenta convertir el segundo operando al tipo del primero o viceversa. Ambos fallan aquí, porque LiveSubscription no es un DisconnectedSubscription y viceversa.
El compilador no comprueba si ambos comparten un tipo de base común.


Tratando de responder a su pregunta en el comentario:

No, las expresiones ternarias no son algún tipo de objeto, sino una expresión ternaria es la parte de la mano derecha de una asignación. Cada expresión de la parte derecha de una tarea tiene un cierto tipo, de lo contrario sería imposible asignar esta expresión a la variable en el lado izquierdo.
Ejemplos:

  • var x = Guid.NewGuid()

    La expresión lado derecho (Guid.NewGuid()) es de tipo Guid, porque el método NewGuid() devuelve un Guid.

  • var x = y.SomeMethod()

    La expresión del lado derecho es del tipo del tipo de retorno de SomeMethod().

  • var x = IsLive ? "a" : 1

    Esto es obviamente inválido, ¿verdad? ¿Qué tipo debe ser x? A string o int?
    Esto daría lugar al mismo mensaje de error exacto que tenía con su código.

  • Su ejemplo un poco cambió:

    var subscription = (IsLive) ? new LiveSubscription() 
              : new DisconnectedSubscription(); 
    

    Nota del var antes subscription, ahora inicializar una nueva variable, no una ya existente. Creo que incluso aquí, es obvio cuál es el problema: ¿qué tipo debería ser subscription? LiveSubscription o DisconnectedSubscription?No puede ser ninguno de los dos, porque dependiendo de IsLive tiene que ser uno o el otro.

Sobre la comparación con if:

En su código, donde se asigna un nuevo LiveSubscription instancia o una nueva DisconnectedSubscription ejemplo a Subscription se está produciendo una conversión implícita a IClientSubscription, porque el compilador sabe que Subscription es de tipo IClientSubscription y tanto LiveSubscription como DisconnectedSubscription se pueden convertir implícitamente a esa interfaz.
La asignación con la expresión ternaria es un poco diferente, porque el compilador primero intenta evaluar la expresión ternaria y solo después intenta asignarla a Subscription. Esto significa que el compilador no sabe que el resultado de la expresión ternaria debe ser del tipo IClientSubscription.

+0

¿Qué quiere decir con "la expresión ternaria es de un cierto tipo"? ¿Qué implicaciones tiene eso para usar una expresión ternaria vs. una declaración if/else equivalente? Tenía la impresión de que una expresión ternaria era azúcar sintáctico simple, pero ¿es alguna vez más? – William

+0

@William: Lea la respuesta completa, especialmente el párrafo después de la oración que citó. Soy de la opinión de que está bastante claro. –

+0

Leí la respuesta completa pero no estoy seguro de las implicaciones que tiene sobre el uso de declaraciones ternaries vs. if. es decir, ¿POR QUÉ son expresiones ternarias de cierto tipo? ¿Son algún tipo de objeto? – William

Cuestiones relacionadas