2012-06-09 20 views
6

Cách toán tử điều kiện (?:) không hoạt động khi được sử dụng với hai kiểu kế thừa từ một loại cơ sở đơn lẻ?Toán tử điều kiện không hoạt động với hai kiểu thừa kế cùng loại cơ sở

Ví dụ tôi có là:

ActionResult foo = (someCondition)? 
         RedirectToAction("Foo","Bar") : 
         Redirect(someUrl); 

Trường hợp dạng dài hoạt động tốt:

ActionResult foo; 

if(someCondition) 
{ 
    foo = RedirectToAction("Foo","Bar"); 
} 
else 
{ 
    foo = Redirect(someUrl); 
} 

Cả hai loại trở lại, RedirectToRouteResultRedirectResult, kế thừa từ ActionResult.

+0

có thể giúp bạn hiển thị tình trạng axact? –

+0

Trong trường hợp này, nó chỉ là một bool. –

+0

thử truyền sang loại cơ sở: (ví dụ: ActionResult foo = (someCondition)? (ActionResult) RedirectToAction ("Foo", "Bar"): (ActionResult) Chuyển hướng (someUrl); ) –

Trả lời

11

Cách toán tử có điều kiện (? :) không hoạt động khi được sử dụng với hai loại kế thừa từ một loại cơ sở đơn lẻ?

Kiểu của biểu thức điều kiện phải là một trong hai kiểu của toán hạng thứ hai hoặc kiểu của toán hạng thứ ba, theo các đặc điểm kỹ thuật ngôn ngữ. Trình biên dịch không cố gắng tìm loại cơ sở chung hoặc loại khác mà cả hai toán hạng đều có thể được chuyển đổi thành. Việc sử dụng sử dụng của biểu thức không ảnh hưởng đến cách loại của nó được xác định - do đó việc gán biến không liên quan ở đây.

Đối với lý do tại sao ngôn ngữ được định nghĩa như thế này - nó giúp việc xác định, triển khai, thử nghiệm và dự đoán đơn giản hơn đáng kể. Điều này là khá phổ biến trong thiết kế ngôn ngữ - giữ ngôn ngữ đơn giản thường là một cược tốt hơn trong thời gian dài, ngay cả khi nó làm cho nó hơi khó xử hơn trong một số tình huống cụ thể.

Xem phần 7.14 của thông số C# 4 để biết thêm chi tiết.

Truyền toán hạng thứ hai hoặc thứ ba sang loại mà bạn thực sự là muốn biểu thức có điều kiện là cách khắc phục sự cố. Lưu ý rằng một tình huống này thường đi lên trong là các loại nullable:

// Invalid 
int? a = SomeCondition ? null : 10; 

// All valid 
int? a = SomeCondition ? (int?) null : 10; 
int? b = SomeCondition ? default(int?) : 10; 
int? c = SomeCondition ? null : (int?) 10; 
+0

Cảm ơn @JonSkeet và cho thêm thông tin và giải pháp cũng có. –

1

Các nhà điều hành có điều kiện không thể xác định loại kết quả từ các thành phần của nó, có thể là một trong hai RedirectToRouteResult hoặc RedirectResult. Để giải quyết điều này, bạn nên bỏ một cách rõ ràng một trong hai (hoặc cả hai) của các thành phần để loại cơ sở:

ActionResult foo = (someCondition) ? 
        (ActionResult)RedirectToAction("Foo","Bar") : 
        Redirect(someUrl); 
1

Phần có điều kiện cố gắng giải quyết riêng của mình không phụ thuộc vào biến nó đang được giao nhiệm vụ. Trình biên dịch đưa ra một cảnh báo rằng nó không thể xác định lớp nào để sử dụng như một giá trị trả về, bởi vì RedirectToRouteResult không thể được đúc giống như RedirectResult, khi mà phần điều kiện có liên quan. Tuy nhiên, nếu chỉ một bên được đúc vào lớp cơ sở, người kia đang ngầm đóng vai tốt, vì vậy casting đầu tiên sẽ có giá trị:

var foo = (someCondition)? 
        (ActionResult)RedirectToAction("Foo","Bar") : 
        Redirect(someUrl); 

nhưng chỉ đúc thay thế quá:

var foo = (someCondition)? 
    RedirectToAction("Foo","Bar") : 
    (ActionResult)Redirect(someUrl);