2009-08-02 35 views
11

tôi sẽ bắt đầu bằng cách giải thích kịch bản của tôi trong mã:C# .NET - Làm thế nào tôi có thể lấy typeof() để làm việc với thừa kế?

public class A { } 

public class B : A { } 

public class C : B { } 

public class D { } 

public class Test 
{ 
    private A a = new A () ; 
    private B b = new B () ; 
    private C c = new C () ; 
    private D d = new D () ; 

    public Test () 
    { 
     // Evaluates to "false" 
     if (a.GetType == typeof(B)) { } //TODO: Add Logic 

     // Evaluates to "true" 
     if (b.GetType == typeof(B)) { } //TODO: Add Logic 

     // I WANT this to evaluate to "true" 
     if (c.GetType == typeof(B)) { } //TODO: Add Logic 

     // Evaluates to "false" 
     if (d.GetType == typeof(B)) { } //TODO: Add Logic 
    } 
} 

Điểm mấu quan trọng phải chú ý đến ở đây là:

if (c.GetType == typeof(B)) { } 

Tôi tin rằng điều này sẽ thực sự đánh giá để " sai ", vì typeof (B) và typeof (C) không bằng nhau theo cả hai hướng. (C là B, nhưng B không nhất thiết phải là C.)

Nhưng điều tôi cần là một số loại điều kiện sẽ tính đến điều này. Làm thế nào tôi có thể nói nếu một đối tượng là một B hoặc bất cứ điều gì bắt nguồn từ nó?

Tôi không quan tâm nếu nó là một đối tượng DERIVED từ B, miễn là lớp B cơ sở có ở đó. Và tôi không thể dự đoán lớp dẫn xuất nào có thể hiển thị trong ứng dụng của tôi. Tôi chỉ phải giả định rằng các lớp dẫn xuất không rõ ràng có thể tồn tại trong tương lai - và do đó tôi chỉ có thể tập trung vào việc đảm bảo rằng lớp cơ sở là những gì tôi mong đợi.

Tôi cần một điều kiện sẽ thực hiện kiểm tra này cho tôi. Làm thế nào điều này có thể được thực hiện?

+0

Bạn nên tránh loại logic này nếu có thể. Khi bạn phải xác định loại có nguồn gốc của một đối tượng là gì, bạn không sử dụng tốt tính đa hình. –

+0

Xem nhận xét của tôi về câu trả lời của Steven Sudit. – Giffyguy

Trả lời

36

Bạn chỉ có thể sử dụng is:

if (c is B) // Will be true 

if (d is B) // Will be false 
+0

Là câu trả lời cho câu hỏi thực tế duy nhất trong OP: "Làm cách nào tôi có thể biết một đối tượng là B hay bất kỳ thứ gì có nguồn gốc từ nó?" Đây là câu trả lời chính xác. Tôi là câu trả lời cho tiêu đề chủ đề, nhưng ít thích hợp hơn cho vấn đề được mô tả. –

+0

Ah, đủ rồi. Bạn là chính xác, câu hỏi của tôi là một chút bối rối ở đó. Lỗi của tôi. – Giffyguy

+0

+1 Đây là giải pháp phù hợp cho vấn đề này. –

19

Chỉnh sửa: câu trả lời cho câu hỏi trong tiêu đề chuỗi. cdm9002 có câu trả lời tốt hơn cho vấn đề như được mô tả trong toàn bộ bài đăng.

typeof(B).IsAssignableFrom(c.GetType()) 
+2

Câu trả lời từ cdm9002 là tốt hơn, vì nó không sử dụng sự phản chiếu. –

+0

@pb: Nếu bạn muốn nhận được kỹ thuật, câu trả lời khác không sử dụng 'typeof' với thừa kế. Như bạn có thể thấy từ bản chỉnh sửa của tôi, tôi không phải là người yêu cầu câu trả lời đầu tiên mà tôi nghĩ là phù hợp nhất.:) –

+2

Đây không chỉ là câu trả lời chính xác, mà còn bao gồm cả trường hợp khi bạn không có cá thể của bất kỳ lớp nào trong tay, nhưng vẫn muốn xác định xem có mối quan hệ thừa kế giữa hai loại hay không. –

4

này trông giống như một việc làm cho đa hình, như trái ngược với một câu lệnh switch lớn với các bài kiểm tra cho các lớp học cụ thể.

+0

Thật vậy. Đặt một phương thức ảo trên lớp A, ghi đè lên thích hợp trong các lớp con, sau đó gọi phương thức ảo này. –

+1

Làm thế nào thô lỗ !! Haha. Logic lớp của tôi không thực sự giống như mớ hỗn độn này. Tôi chỉ cần tìm ra cách để thực hiện điều kiện này. Tôi đang viết một phương thức PropertyChangedCallback Trong lớp cơ sở trừu tượng và tôi cần một điều kiện bảo mật để đảm bảo rằng tham số DependencyObject là một đối tượng bắt nguồn từ lớp cơ sở của tôi. Nếu không, tôi ném một lỗi hoặc hủy bỏ logic của tôi. Đa hình không hữu ích trong trường hợp này. – Giffyguy

+1

Ok, sau đó sử dụng "is" là đủ. –

0

Đối với VB.NET với Visual Studio     2008, bạn có thể kiểm tra xem nó thích:

'MyTextBox control is inherited by Textbox 
If Ctl.GetType.Name = "MyTextBox" then  

End If 
1

Để thay thế cho việc kiểm tra (c is B), bạn cũng có thể làm như sau:

var maybeB = c as B; 
if (maybeB != null) { 
    // make use of maybeB 
} 

Điều này được ưu tiên trong một số trường hợp vì để sử dụng c làm B khi sử dụng is, bạn vẫn phải truyền.

0
typeof(B).IsInstanceOfType(c) 

Tương tự như câu trả lời ở trên từ sam-harwell, đôi khi bạn có thể có loại "B" trong biến, vì vậy bạn cần sử dụng phản chiếu thay vì toán tử "is".

Tôi đã sử dụng giải pháp của Sam và thật ngạc nhiên khi Resharper đưa ra đề xuất này.

Các vấn đề liên quan