2015-01-07 8 views
13

Ho la seguente azione ASP.NET Web Api 2 con un ternario se ritorno:"non può essere determinato, perché non v'è alcuna conversione implicita" con ternery se ritorno

[HttpDelete] 
public IHttpActionResult Delete() 
{ 
    bool deleted; 

    // ... 

    return deleted ? this.Ok() : this.NotFound(); 
} 

Riceverò una

Tipo di espressione condizionale non può essere determinato perché non c'è alcuna conversione implicita tra 'System.Web.Http.Results.OkResult' e 'System.Web.Http.Results.NotFoundResult'

quando entrambi implementano IHttpActionResult.

Tuttavia se mi tolgo la ternario se, il compilatore è felice:

if (deleted) 
{ 
    return this.Ok(); 
} 
return this.NotFound(); 

perché è questo?

risposta

14

È necessario lanciare esplicitamente il risultato IHttpActionResult:

return deleted ? (IHttpActionResult) this.Ok() : this.NotFound(); 

Edit:

Nel settore delle sovvenzioni domanda:

Perché secondo blocco di lavoro di codice di Sam, senza esplicitamente casting to IHttpActionResult, solo per curiosità? Si tratta di qualcosa di particolare per l'operatore condizionale?:?

Consente di creare una semplice dimostrazione. Si supponga il seguente codice:

public interface IFoo { } 

public class B : IFoo { } 

public class C : IFoo { } 

E allora la seguente:

public class A 
{ 
    IFoo F(bool b) 
    { 
     return b ? (IFoo) new B() : new C(); 
    } 
} 

Vediamo come il compilatore de-compila l'operatore ternario:

private IFoo F(bool b) 
{ 
    IFoo arg_13_0; 
    if (!b) 
    { 
     IFoo foo = new C(); 
     arg_13_0 = foo; 
    } 
    else 
    { 
     arg_13_0 = new B(); 
    } 
    return arg_13_0; 
} 

Il cast esplicito è sufficiente per il compilatore per dedurre che la variabile dovrebbe essere di tipo IFoo e quindi soddisfare il nostro intero if-else. Questo è il motivo per cui è sufficiente per noi "suggerire" al compilatore solo una volta il cast del nostro tipo.

@dcastro ha fatto riferimento alla parte esatta della specifica del linguaggio che determina il controllo del tipo, vedere quello per la definizione del libro di testo.

+2

Perché secondo blocco di lavoro di codice di Sam, senza esplicitamente colata a 'IHttpActionResult', appena fuori curiosità? È qualcosa di particolare per l'operatore condizionale '?:'? –

+0

@GrantWinney Sì, è – dcastro

+0

@GrantWinney Vedere la mia risposta modificata. –

6

In un'espressione ternaria A? B : C, ci deve essere una conversione riferimento (ad esempio, da un tipo di base di un tipo derivato o viceversa) sia da B a C o C a B.

È previsto il compilatore per trovare l'antenato comune più derivato dei due tipi (che è IHttpActionResult) - il compilatore non lo fa.

Come regola generale, il tipo di risultato di qualsiasi espressione deve essere contenuto all'interno dell'espressione stessa. Cioè, bool? dog : cat non può restituire un animal perché nessuna variabile di tipo animal fa parte dell'espressione.

Dalla sezione C# Language Specification 7.14 operatore condizionale:

Il secondo e terzo operandi, x ed y, da: comando del tipo dell'espressione condizionale.

  • Se x ha tipo X e Y ha tipo Y poi
    • Se una conversione implicita (§6.1) esiste da X a Y, ma non da Y a X, allora Y è il tipo del condizionale espressione
    • Se esiste una conversione implicita (§6.1) da Y a X, ma non da X a Y, X è il tipo di espressione condizionale .
    • In caso contrario, nessun tipo di espressione può essere determinato, e un errore in fase di compilazione si verifica