Làm thế nào để kiểm tra xem một đối tượng có phương thức / thuộc tính nhất định không?


155

Sử dụng mô hình động có lẽ? Bạn có thể gọi bất kỳ phương thức / thuộc tính nào bằng cách sử dụng từ khóa động, phải không? Làm thế nào để kiểm tra xem phương thức có tồn tại hay không trước khi gọi myDocateObject.DoStuff () chẳng hạn?


Loại myD bitObject là gì? Đây có phải là một lớp học bắt nguồn từ DynamicObject?
Cheng Chen

một cái gì đó được khai báo với từ khóa động
Louis Rhys

Câu trả lời:


224

Bạn có thể viết một cái gì đó như thế:

public static bool HasMethod(this object objectToCheck, string methodName)
{
    var type = objectToCheck.GetType();
    return type.GetMethod(methodName) != null;
} 

Chỉnh sửa: bạn thậm chí có thể thực hiện một phương thức mở rộng và sử dụng nó như thế này

myObject.HasMethod("SomeMethod");

GetType () sẽ trả về kiểu thời gian chạy? (tức là không phải đối tượng?)
Louis Rhys

2
có, GetType () trả về kiểu đang chạy trong khi typeof () sẽ trả về đối tượng.
Julien

1
Theo các tài liệu GetType () sẽ trả về "Kiểu thời gian chạy chính xác của thể hiện hiện tại".
tzup

Ngoài ra, phương thức mở rộng sẽ cần phải tĩnh.
Fraser

9
Tôi thích viết: objectToCheck.GetType (). GetMethod (methodName)! = Null
efirat

85

thông qua sự phản ánh

 var property = object.GetType().GetProperty("YourProperty")
 property.SetValue(object,some_value,null);

Tương tự là cho các phương thức


Đẹp. Bạn cũng có thể thực hiện GetMethod trong một vòng lặp để có được thuộc tính được xác định phù hợp.
Jnr

Hữu ích cho việc lặp qua danh sách các điều khiển UI được liên kết và Cha mẹ của chúng
Chicowitz

Trong GetType()đó có phương pháp như thế nào GetProperties(). Nó đang trả về mảng của PropertyInfo. Nhưng làm thế nào tôi có thể sử dụng GetProperties()phương pháp?
Yogesh Patel

43

Đó là một câu hỏi cũ, nhưng tôi chỉ gặp phải nó. Type.GetMethod(string name)sẽ đưa ra một AmbiguptMatchException nếu có nhiều hơn một phương thức có tên đó, vì vậy chúng tôi xử lý trường hợp đó tốt hơn

public static bool HasMethod(this object objectToCheck, string methodName)
{
    try
    {
        var type = objectToCheck.GetType();
        return type.GetMethod(methodName) != null;
    }
    catch(AmbiguousMatchException)
    {
        // ambiguous means there is more than one result,
        // which means: a method with that name does exist
        return true;
    }
} 

18

Sẽ không tốt hơn nếu không sử dụng bất kỳ loại động nào cho việc này và để lớp của bạn thực hiện một giao diện. Sau đó, bạn có thể kiểm tra trong thời gian chạy khi một đối tượng thực hiện giao diện đó và do đó, có phương thức (hoặc thuộc tính) dự kiến.

public interface IMyInterface
{
   void Somemethod();
}


IMyInterface x = anyObject as IMyInterface;
if( x != null )
{
   x.Somemethod();
}

Tôi nghĩ rằng đây là cách duy nhất đúng.

Điều bạn đang đề cập đến là gõ vịt, rất hữu ích trong các tình huống mà bạn đã biết rằng đối tượng có phương thức, nhưng trình biên dịch không thể kiểm tra điều đó. Điều này rất hữu ích trong các kịch bản tương tác COM chẳng hạn. (kiểm tra này bài viết)

Nếu bạn muốn kết hợp gõ vịt với phản chiếu chẳng hạn, thì tôi nghĩ bạn đang thiếu mục tiêu gõ vịt.


2
Điều gì xảy ra nếu đối tượng có thể là một đối tượng được cung cấp bởi .NET framework và tôi không thể khai báo nó để thực hiện bất cứ điều gì?
Louis Rhys

Có vấn đề gì vậy? Bạn có thể kiểm tra xem 'đối tượng' có phải là một đối tượng như vậy không, được cung cấp bởi .NET framework theo cùng một cách
Frederik Gheysels

ví dụ, bạn muốn kiểm tra xem có phương thức "Thêm" trong một đối tượng hay không. ANd đối tượng có thể là Danh sách <int> hoặc một số lớp khác không phải là IEn Countable
Louis Rhys

3
Có lẽ bạn nên xem kịch bản một sản phẩm Adobe bằng COM. Cuộc gọi chức năng tương tự có thể trả về các đối tượng COM hoàn toàn khác nhau và theo thiết kế (của Adobe), tổ tiên chung duy nhất của chúng là đối tượng. Ngoài ra: đây là một mô hình phổ biến trong hầu hết mọi ngôn ngữ kịch bản động hiện đại (Python, Javascript, VB script, PHP, Lua ... tôi có thể tiếp tục và tiếp tục). Nó không phải là một lỗi, đó là một tính năng.
Tim Keat

5
Đó là một mùi nhưng nó được tạo ra bởi microsoft. Nhìn vào WebControls như Nút, LinkButton, v.v ... Cả hai đều triển khai thuộc tính OnClientClick nhưng, giả sử, ListControl và Bảng điều khiển thì không. OnClientClick không được xác định trong giao diện nên sự phản chiếu là tùy chọn duy nhất.
HammerIp
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.