2010-06-10 38 views
51

Trong khi cố gắng tìm hiểu Unity, tôi tiếp tục nhìn thấy đoạn mã sau cho trọng GetControllerInstance trong MVC:Sử dụng IsAssignableFrom và "là" từ khóa trong C#

if(!typeof(IController).IsAssignableFrom(controllerType)) { ... } 

này dường như với tôi một cách khá phức tạp của cơ bản viết

if(controllerType is IController) { ... } 

tôi đánh giá cao có sự khác biệt tinh tế giữa isIsAssignableFrom, tức là IsAssignableFrom không bao gồm chuyển đổi diễn viên, nhưng tôi đang gặp khó khăn để hiểu được ý nghĩa của differenc này e trong các tình huống thực tế.

Khi nào bạn nên chọn IsAssignableFrom hơn is? Điều gì sẽ khác biệt trong GetControllerExample?

if (!typeof(IController).IsAssignableFrom(controllerType)) 
     throw new ArgumentException(...); 
return _container.Resolve(controllerType) as IController; 

Trả lời

80

Không giống nhau.

if(controllerType is IController) 

sẽ luôn đánh giá để false từ controllerType luôn luôn là một Type, và một Type không bao giờ là một IController.

Toán tử is được sử dụng để kiểm tra xem một ví dụ có tương thích với một loại nhất định hay không.

Phương pháp IsAssignableFrom được sử dụng để kiểm tra xem Loại có tương thích với một loại nhất định hay không.

+0

Ah ok sự khác biệt là hiển nhiên bây giờ. Tôi nên phát hiện ra điều đó! – fearofawhackplanet

+0

Vì vậy, tôi đoán là nếu 'T' và' U' là loại chung thì 'typeof (T) .IsAssignableFrom (typeof (U))' có giống 'new T() là U' không? – orad

+1

Không, nhưng nó sẽ giống với 'new U() là T'. T sẽ là loại cơ sở. Tôi luôn bị vấp ngã bởi điều đó. Tôi chỉ nhớ rằng 'IsAssignableFrom' đối diện với toán tử' is'. – Jordan

16

is từ khóa chỉ áp dụng cho các trường hợp trong khi Type.IsAssignableFrom() chỉ áp dụng cho các loại.

ví dụ về is

string str = "hello world"; 
if(str is String) 
{ 
    //str instance is of type String 
} 

Lưu ý rằng str là một thể hiện và không phải là loại.

ví dụ về IsAssignableFrom()

string str = "hello world"; 
if(typeof(Object).IsAssignableFrom(str.GetType())) 
{ 
    //instances of type String can be assigned to instances of type Object. 
} 

if(typeof(Object).IsAssignableFrom(typeof(string))) 
{ 
    //instances of type String can be assigned to instances of type Object. 
} 

Lưu ý rằng, lập luận để IsAssignableFrom() không phải là trường hợp của String, đó là loại đối tượng đại diện String loại.

21

typeof(IController).IsAssignableFrom(controllerType) kiểm tra Type đối với giao diện. Toán tử is kiểm tra một phiên bản chống lại giao diện.

+2

Nhận xét này rõ ràng nhất đối với tôi. – Phil

5

Một sự khác biệt đáng chú ý cũng là 'là' làm cho cảm giác trực quan để kiểm tra thừa kế hoặc thực hiện giao diện, trong khi IsAssignableFrom làm bất cứ điều gì nhưng ý nghĩa trên khuôn mặt của nó. Tên của phương thức Type.IsAssignableFrom là mơ hồ và khó hiểu khi được áp dụng để kiểm tra thừa kế hoặc phát hiện các giao diện triển khai.Các wrapper sau cho những mục đích này sẽ làm cho nhiều trực quan hơn, mã ứng dụng có thể đọc được:

public static bool CanBeTreatedAsType(this Type CurrentType, Type TypeToCompareWith) 
    { 
     // Always return false if either Type is null 
     if (CurrentType == null || TypeToCompareWith == null) 
      return false; 

     // Return the result of the assignability test 
     return TypeToCompareWith.IsAssignableFrom(CurrentType); 
    } 

Sau đó, người ta có thể có cú pháp khách hàng hiểu hơn như:

bool CanBeTreatedAs = typeof(SimpleChildClass).CanBeTreatedAsType(typeof(SimpleClass)); 
    CanBeTreatedAs = typeof(SimpleClass).CanBeTreatedAsType(typeof(IDisposable)); 

Ưu điểm của phương pháp này thay cho 'là' từ khóa là nó có thể được sử dụng trong thời gian chạy để kiểm tra các loại không xác định, tùy ý, trong khi từ khoá 'là' (và một tham số kiểu chung) đòi hỏi kiến ​​thức biên dịch về các loại cụ thể.

+0

Tôi không thấy cách 'IsAssignableFrom' hoàn toàn không trực quan. Trong một hệ thống kiểu đa hình, bất kỳ kiểu nào cũng có thể được gán một giá trị từ bất kỳ kiểu con nào của nó, tức là bạn có thể làm một cái gì đó như: 'SimpleBaseClass myVar = new SimpleChildClass()'. 'IsAssignableFrom' cho bạn biết việc gán phép đa hình như vậy có hợp pháp hay không, và do đó một kiểu có phải là một kiểu con hay tương đương với một kiểu khác hay không. – zstewart

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