2010-07-15 46 views
15

mẫu mã lấy từ MSDNtại sao Object.GetType() không phải là ảo?

public class Test { 
public static void Main() { 
    MyBaseClass myBase = new MyBaseClass(); 
    MyDerivedClass myDerived = new MyDerivedClass(); 
    object o = myDerived; 
    MyBaseClass b = myDerived; 

    Console.WriteLine("mybase: Type is {0}", myBase.GetType()); 
    Console.WriteLine("myDerived: Type is {0}", myDerived.GetType()); 
    Console.WriteLine("object o = myDerived: Type is {0}", o.GetType()); 
    Console.WriteLine("MyBaseClass b = myDerived: Type is {0}", b.GetType()); }} 

/* 
This code produces the following output. 
mybase: Type is MyBaseClass 
myDerived: Type is MyDerivedClass 
object o = myDerived: Type is MyDerivedClass 
MyBaseClass b = myDerived: Type is MyDerivedClass 
*/ 

Vì vậy, nó sẽ là hợp lý để làm cho GetType() ảo ít nhất nó hoạt động như ảo? Ai có thể giải thích điều đó không? Và câu hỏi khác Có bất kỳ phương pháp nào khác trong NET framework có hành vi giống như GetType không?

Trả lời

16

vì .Net framework không muốn bạn ghi đè phương thức GetType() và spoof về loại.

giả sử bạn có thể ghi đè lên phương thức bạn muốn làm gì khác hơn là trả về loại cá thể. và khi bạn ghi đè lên phương thức cho mỗi lớp của bạn để trả về kiểu của cá thể, bạn sẽ không vi phạm DRY sau đó.

+3

và hợp lý như vậy! –

+0

có. bạn đúng. nhưng bạn có thể quá tải phương thức công khai này trong lớp dẫn xuất)) – Arseny

+2

@Arseny: Sau đó, nó không giống như GetType() như được định nghĩa trên kiểu đối tượng. –

2

GetType trả về Loại thực tế của đối tượng. Điều này cho phép chúng ta biết đối tượng nào thực sự được truyền cho hàm 'của chúng ta'. Nhiều phương thức của khung công tác cần điều này để xác định chức năng của riêng chúng - trong hầu hết các trường hợp để có được các thuộc tính của lớp này. Nếu Khung sẽ mất khả năng xác định loại thực của đối tượng, thì đối tượng cũng sẽ mất loại này.

Nếu bạn muốn biết các loại được sử dụng trong phạm vi phương pháp của bạn - loại bạn tuyên bố hoặc đã được chọn bởi trình biên dịch - bạn có thể thêm một phương pháp khuyến nông khá đơn giản:

public static Type GetCurrentType<T>(this T obj) 
{ 
    return typeof(T); 
} 

public static void Main() 
{ 
    MyBaseClass myBase = new MyBaseClass(); 
    MyDerivedClass myDerived = new MyDerivedClass(); 
    object o = myDerived; 
    MyBaseClass b = myDerived; 

    Console.WriteLine("mybase: Type is {0}", myBase.GetCurrentType()); 
    Console.WriteLine("myDerived: Type is {0}", myDerived.GetCurrentType()); 
    Console.WriteLine("object o = myDerived: Type is {0}", o.GetCurrentType()); 
    Console.WriteLine("MyBaseClass b = myDerived: Type is {0}", b.GetCurrentType()); 
} 

/* 
This code produces the following output. 
mybase: Type is ValidatorTest.MyBaseClass 
myDerived: Type is ValidatorTest.MyDerivedClass 
object o = myDerived: Type is System.Object 
MyBaseClass b = myDerived: Type is ValidatorTest.MyBaseClass 
*/ 
2

Nếu GetType() là ảo, một lớp có tên là HumanBeing có thể ghi đè lên nó và trả về một đối tượng Kiểu đại diện cho Robot được gọi là giả mạo và ngăn chặn đây là một trong những tính năng chính của CLR được gọi là Loại an toàn.

2

Mặc dù đúng là bạn không thể ghi đè đối tượng.GetType(), bạn có thể sử dụng "mới" để quá tải hoàn toàn, do đó giả mạo một loại đã biết khác. Điều này là thú vị, tuy nhiên, tôi đã không tìm ra cách để tạo ra một thể hiện của đối tượng "Loại" từ đầu, vì vậy ví dụ dưới đây giả vờ là một loại khác.

public class NotAString 
{ 
    private string m_RealString = string.Empty; 
    public new Type GetType() 
    { 
     return m_RealString.GetType(); 
    } 
} 

Sau khi tạo trường hợp này, (mới NotAString()). GetType(), thực sự sẽ trả về loại cho chuỗi.

+1

Bởi hầu như bất cứ điều gì mà nhìn vào 'GetType' có một thể hiện của' đối tượng', hoặc ít nhất là một số loại cơ sở mà họ kiểm soát hoặc có thể lý do. Nếu bạn đã có một thể hiện của kiểu được sinh ra nhiều nhất thì không cần phải gọi 'GetType' trên nó. Vấn đề là miễn là ai đó sử dụng 'GetType' trên một' đối tượng' họ có thể chắc chắn đó là việc triển khai của hệ thống, không phải bất kỳ định nghĩa tùy chỉnh nào khác. – Servy

0

Sửa Dr Snooze của answer, để "tạo ra một thể hiện của 'Loại' đối tượng từ đầu":

public class NotAString 
{ 
    public new Type GetType() 
    { 
     return typeof(string); 
    } 
} 
Các vấn đề liên quan