2015-01-07 38 views
13

Tôi đã sau hành động ASP.NET Web Api 2 với một ternary nếu trở lại:"Không thể xác định được vì không có chuyển đổi ngầm" với ternery nếu trở lại

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

    // ... 

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

tôi nhận được một

Loại biểu thức điều kiện không xác định được vì không không chuyển đổi ngầm giữa 'System.Web.Http.Results.OkResult' và 'System.Web.Http.Results.NotFoundResult'

khi cả hai đều triển khai IHttpActionResult.

Tuy nhiên nếu tôi loại bỏ các ternary nếu, trình biên dịch là hạnh phúc:

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

Tại sao điều này?

Trả lời

14

Bạn cần phải rõ ràng đúc kết quả để IHttpActionResult:

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

Edit:

Như Grants câu hỏi:

Tại sao khối thứ hai của Sam công việc mã mà không rõ ràng truyền tới IHttpActionResult, chỉ vì tò mò? Đây có phải là cái gì đó cụ thể cho toán tử điều kiện ?: không?

Cho phép tạo trình diễn đơn giản. Giả sử đoạn mã sau:

public interface IFoo { } 

public class B : IFoo { } 

public class C : IFoo { } 

Và sau đó như sau:

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

Cho phép xem cách trình biên dịch de-biên dịch các nhà điều hành ternary:

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; 
} 

Các diễn viên rõ ràng là đủ cho trình biên dịch để suy ra rằng biến phải thuộc loại IFoo và do đó đáp ứng toàn bộ số if-else của chúng tôi. Đó là lý do tại sao nó là đủ cho chúng tôi để "gợi ý" trình biên dịch chỉ một lần của chúng tôi loại đúc.

@dcastro đã tham chiếu phần chính xác của đặc tả ngôn ngữ xác định việc kiểm soát loại, xem định nghĩa sách văn bản.

+2

Tại sao khối thứ hai của Sam công việc mã mà không rõ ràng đúc cho 'IHttpActionResult', chỉ cần ra khỏi sự tò mò? Đây có phải là cái gì đó đặc biệt đối với toán tử điều kiện '?:' Không? –

+0

@GrantWinney Có phải là – dcastro

+0

@GrantWinney Xem câu trả lời đã chỉnh sửa của tôi. –

6

Trong một biểu ternary A? B : C, phải có một sự chuyển đổi tham khảo (ví dụ, từ một loại cơ sở để một loại có nguồn gốc hoặc ngược lại) từ một trong hai B đến C hoặc C đến B.

Bạn mong đợi trình biên dịch để tìm tổ tiên chung có nguồn gốc phổ biến nhất của hai loại (đó là IHttpActionResult) - trình biên dịch không làm điều đó.

Theo nguyên tắc chung, loại kết quả của bất kỳ biểu thức nào phải được chứa trong chính cụm từ đó. I E., bool? dog : cat không thể trả về số animal vì không có biến loại animal là một phần của biểu thức.

Từ điều hành có điều kiện phần C# Language Specification 7,14:

Các toán hạng thứ hai và thứ ba, x và y, của: kiểm soát hành kiểu của biểu thức điều kiện.

  • Nếu x có kiểu X và y có kiểu Y sau đó
    • Nếu một chuyển đổi ngầm (§6.1) tồn tại từ X thành Y, nhưng không phải từ Y đến X, sau đó Y là kiểu của điều kiện biểu thức
    • Nếu chuyển đổi ẩn (§6.1) tồn tại từ Y thành X, nhưng không phải từ X thành Y, thì X là loại biểu thức điều kiện .
    • Nếu không, không có loại biểu thức có thể được xác định, và một lỗi thời gian biên dịch xảy ra
Các vấn đề liên quan