Tôi thực hiện phân tích kiểu nào đó trong thời gian chạy bằng Phản chiếu. Nếu tôi có một cá thể MethodInfo, làm thế nào tôi có thể tìm ra nếu đây là phương pháp "thực" hoặc là phương thức getter/setter của một thuộc tính? Và nếu nó là một tài sản, làm thế nào tôi có thể tìm thấy nó lưu trữ PropertyInfo trở lại?Tìm tài sản lưu trữ PropertyInfo từ MethodInfo của getter/setter
Trả lời
Ecma 335 chỉ định (nhưng không yêu cầu) trình biên dịch sử dụng tiền tố get_/set_ (chương 22.28). Tôi không biết bất kỳ ngôn ngữ nào phá vỡ đề xuất đó. Làm cho nó dễ dàng:
public static PropertyInfo GetPropFromMethod(Type t, MethodInfo method) {
if (!method.IsSpecialName) return null;
return t.GetProperty(method.Name.Substring(4),
BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
}
Vâng, phương pháp đằng sau phương thức getter và setter là "thực".
Theo dõi lại thuộc tính - mẫu (return vs take 1 arg) sẽ giúp thu hẹp nó - nhưng bạn sẽ phải gọi GetGetMethod/GetSetMethod trên mỗi để tìm thuộc tính.
Bạn có thể có thể thử số Name
(ít nhận __/set__) - nhưng cảm thấy dễ vỡ. Đây là phiên bản dài hơn (không sử dụng số Name
):
static PropertyInfo GetProperty(MethodInfo method)
{
bool takesArg = method.GetParameters().Length == 1;
bool hasReturn = method.ReturnType != typeof(void);
if (takesArg == hasReturn) return null;
if (takesArg)
{
return method.DeclaringType.GetProperties()
.Where(prop => prop.GetSetMethod() == method).FirstOrDefault();
}
else
{
return method.DeclaringType.GetProperties()
.Where(prop => prop.GetGetMethod() == method).FirstOrDefault();
}
}
+1 cho giải pháp thay thế, vẫn thích 'name.StartsWith ("get_"/"set_")'. – arul
hmm ... có thể cho mã C#, ít nhất ... chúng được đề cập trong 17.2.7.1 của ECMA 335 - nhưng điều này có được áp dụng cho các ngôn ngữ khác không? Tôi sẽ kiểm tra ECMA 334 ... –
Chắc chắn là, hãy kiểm tra phần 17.2.7.1. Đối với thuộc tính P thuộc loại T, các chữ ký sau đây được đặt trước: T get_P(); void set_P (giá trị T); Cả hai chữ ký đều được bảo lưu, ngay cả khi thuộc tính chỉ đọc hoặc chỉ ghi. – arul
Nhìn vào MethodBase.IsSpecialName
. Các phương thức không được hiển thị rõ ràng, chẳng hạn như các trình truy cập thuộc tính, các phương thức đăng ký sự kiện và các toán tử quá tải sử dụng cờ này.
Theo hiểu biết của tôi, không có cách nào để tìm số PropertyInfo
mà không cần lặp qua các thuộc tính và so sánh các phương pháp.
Theo MS, bạn không thể đảm bảo rằng cờ IsSpecialName sẽ được đặt: http://connect.microsoft.com/VisualStudio/feedback/details/108302/for-property-accessors-get-set-isspecialname-false –
IsSpecialName dường như không hoạt động. Tôi hy vọng đây là một cái gì đó MS thay đổi bởi vì nó tốt hơn để có thể kiểm tra lá cờ hơn là phải lý do những gì các tính năng ngôn ngữ được thực hiện như (có thể không đánh dấu) phương pháp đặc biệt. –
Tôi thực sự muốn rời khỏi đây như một lời nhận xét, nhưng tôi không thể kể từ khi đại diện của tôi isnt đủ cao :(
Theres một lỗi trong mã Marc Gravell của: nếu nó một indexer nó sẽ trả về null, ngay cả khi một tài sản cha mẹ tồn tại của nó tốt đẹp để có mà nhanh chóng thất bại, nhưng tôi nghĩ rằng chúng tôi chỉ có thể làm như vậy khi nó có phải là một giá trị trả về hoặc một tham số:.
[Pure]
public static PropertyInfo GetParentProperty(this MethodInfo method)
{
if (method == null) throw new ArgumentNullException("method");
var takesArg = method.GetParameters().Length == 1;
var hasReturn = method.ReturnType != typeof(void);
if (!(takesArg || hasReturn)) return null;
if (takesArg && !hasReturn)
{
return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetSetMethod() == method);
}
else
{
return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetGetMethod() == method);
}
}
Bí quyết để chơi với là BindingFlags.DeclaredOnly và IsSpecialName
- 1. Lưu trữ tài liệu từ
- 2. RavenDB lưu trữ tài sản với thuộc tính JsonIgnore
- 3. Override tài sản của tài
- 4. Sharepoint Tìm kiếm tài sản trọng số
- 5. Tại sao Rails không tìm thấy tài sản của tôi?
- 6. Làm thế nào để tìm kiếm bất kỳ tài sản nào từ một bảng với LINQ?
- 7. JSP, EL tài sản không tìm thấy
- 8. Đặt giá trị tài sản tên sử dụng tài sản
- 9. tài sản heroku không tìm thấy 404
- 10. WCF: Lấy MethodInfo từ OperationContext
- 11. Chuyển máy chủ lưu trữ tài sản cho bộ điều khiển
- 12. tài sản hibernate không tìm thấy
- 13. Sử dụng PropertyInfo để tìm ra loại thuộc tính
- 14. Cách bảo mật tài sản được lưu trữ trong Android APK
- 15. ARC cấm tổng hợp một tài sản với quyền sở hữu hoặc lưu trữ
- 16. Lưu trữ tài liệu tư nhân Sphinx
- 17. Làm cách nào để lấy tên của một tài sản từ một tài sản trong C# (2.0)
- 18. Tài sản tên của NSCache
- 19. Cách tải tài nguyên từ thư mục WEB-INF của lưu trữ web
- 20. Cải thiện hiệu suất của việc lấy MethodInfo từ MethodCallExpression
- 21. Đẩy từ kho lưu trữ cục bộ sang GitHub được lưu trữ từ xa
- 22. Nhận thuộc tính DisplayAttribute từ PropertyInfo
- 23. Lưu trữ các sản phẩm magento 1.5 ở đâu?
- 24. Gọi một Kho lưu trữ từ Kho lưu trữ
- 25. Sản phẩm Xcode -> Lưu trữ bị vô hiệu hóa
- 26. tài sản Groovy lặp
- 27. Chiều dài tối đa của FormsAuthenticationTicket.UserData tài sản
- 28. Kho lưu trữ/thư mục lưu trữ của Eclipse
- 29. "phương pháp thiết lập tài sản không tìm thấy" lỗi trong quá trình phản ánh
- 30. Cải thiện mã theo dõi tài sản?
Từ văn bản thông tin, nó được yêu cầu phải tuân thủ CLS, nhưng không bắt buộc phải là hợp lệ IL. –
Tôi sẽ không khuyên bạn nên đi theo cách này. Tôi khuyên bạn nên kiểm tra tất cả các thuộc tính. Quy ước mẫu chuỗi - không mạnh mẽ. –
Tôi rất muốn xem một ví dụ phản đối. –