2012-07-12 20 views
21

Tôi có thể nhận tài sản của mình bằng cách nào? Hiện tại, lỗi xảy ra là Ambiguous match found, hãy xem dòng nhận xét trong mã.Kết quả phản hồi có ưu thế trong "Kết quả không rõ ràng được tìm thấy" trên thuộc tính mới

public class MyBaseEntity 
{ 
    public MyBaseEntity MyEntity { get; set; } 
} 

public class MyDerivedEntity : MyBaseEntity 
{ 
    public new MyDerivedEntity MyEntity { get; set; } 
} 

private static void Main(string[] args) 
{ 
    MyDerivedEntity myDE = new MyDerivedEntity(); 

    PropertyInfo propInfoSrcObj = myDE.GetType().GetProperty("MyEntity"); 
    //-- ERROR: Ambiguous match found 
} 
+1

Lỗi thời gian chạy hoặc lỗi biên dịch? –

+1

@Valamas Vui lòng xem xét lại câu trả lời đã chọn. Nhiều người sẽ đến đây với các cấu trúc có điều kiện như 'if (winform.GetType(). GetProperty (" Items ")! = Null) {..}' trong trường hợp này, người ta chỉ đơn thuần chuyển đổi Exceptions bằng cách sử dụng LINQ ... –

Trả lời

24

Type.GetProperty

tình huống trong đó AmbiguousMatchException xảy ra ...

... loại có nguồn gốc khai báo một tài sản mà giấu đi một tài sản có cùng tên được thừa hưởng, bằng cách sử dụng các từ khóa new

Nếu bạn chạy sau

var properties = myDE.GetType().GetProperties().Where(p => p.Name == "MyEntity"); 

bạn sẽ thấy rằng hai đối tượng PropertyInfo được trả lại. Một cho MyBaseEntity và một cho MyDerivedEntity. Đó là lý do tại sao bạn nhận được Trận đấu mơ hồ đã tìm thấy lỗi.

Bạn có thể lấy PropertyInfo cho MyDerivedEntity như thế này:

PropertyInfo propInfoSrcObj = myDE.GetType().GetProperties().Single(p => 
    p.Name == "MyEntity" && p.PropertyType == typeof(MyDerivedEntity)); 
+2

+1. Tốt tay trên lời giải thích. Tôi đã thêm liên kết RTFM chỉ trong trường hợp. –

+0

những thứ tuyệt vời! Tôi đã đơn giản hóa nó thành 'type.GetProperties(). Đầu tiên (p => p.Name ==" MyEntity ")' Tất cả các bài kiểm tra đều có màu xanh lá cây! –

+1

Bất kể 'First' hoặc' Single', cả hai sẽ ** ném một ngoại lệ khi không có phần tử nào ** để bắt đầu! –

5

Kevin đã chỉ ra vấn đề này, nhưng bạn không cần phải báo cáo phức tạp, hoặc LINQ cho rằng:

PropertyInfo propInfoSrcObj = myDE.GetType(). 
    GetProperty("MyEntity", typeof(MyDerivedEntity)); 
16

Đối thuộc tính:

MemberInfo property = myDE.GetProperty(
    "MyEntity", 
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); 

Phương thức:

MemberInfo method = typeof(String).GetMethod(
    "ToString", 
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, 
    null, 
    new Type[] { },// Method ToString() without parameters 
    null); 

BindingFlags .DeclaredOnly - Chỉ định rằng các thành viên được khai báo ở cấp phân cấp của loại được cung cấp phải được xem xét. Các thành viên thừa kế không được xem xét.

0

Tôi gặp sự cố này với việc tuần tự hóa MsgPack đối tượng LocationKey của mình. Cuối cùng là các toán tử mà tôi đã định nghĩa trong lớp LocationKey của mình. Có cả hai toán tử được xác định này gây ra DefaultContext.GetSerializer(obj.GetType()); để ném Tìm kiếm phù hợp không rõ ràng khi cố gắng sắp xếp theo thứ tự. Việc xóa một nhóm toán tử đã khiến vấn đề biến mất.

public static bool operator ==(int key1, LocationKey key2) 
{ 
    return key1 == key2.Value; 
} 

public static bool operator !=(int key1, LocationKey key2) 
{ 
    return key1 != key2.Value; 
} 

public static bool operator ==(LocationKey key1, int key2) 
{ 
    return key1.Value == key2; 
} 

public static bool operator !=(LocationKey key1, int key2) 
{ 
    return key1.Value != key2; 
} 
9

Sự mơ hồ xảy ra do tuyên bố new trong MyDerivedEntity. Để khắc phục điều này, bạn có thể sử dụng LINQ:

var type = myObject.GetType(); 
var colName = "MyEntity"; 
var all = type.GetProperties().Where(x => x.Name == colName); 
var info = all.FirstOrDefault(x => x.DeclaringType == type) ?? all.First(); 

Điều này sẽ lấy thuộc tính ra khỏi loại có nguồn gốc nếu nó tồn tại, nếu không cơ sở. Điều này có thể dễ dàng được flip-flopped nếu cần thiết.

+1

Đó là giải pháp phổ quát và mở rộng thực sự. – it3xl

+1

Giải pháp rất hiệu quả! Nhưng tôi lo sợ thứ tự của các thuộc tính không được bảo đảm: _M method 'M: System.Type.GetProperties' không trả về các thuộc tính theo thứ tự cụ thể, chẳng hạn như thứ tự bảng chữ cái hoặc thứ tự khai báo. Mã của bạn không được phụ thuộc vào thứ tự mà các thuộc tính được trả về, bởi vì thứ tự đó khác nhau._ (Lấy từ [Tài liệu MSDN] (https://msdn.microsoft.com/en-us/library/aky14axb.aspx#Anchor_1)) – KnorxThieus

+0

Một giải pháp tốt hơn và phổ biến hơn so với câu trả lời được chấp nhận rộng rãi ở đầu –

1

tôi đã nhận lỗi này, tôi tìm kiếm nó trong trình duyệt của giao diện điều khiển và tôi thấy ngoại lệ này là dành cho C# và câu trả lời cũng là cho C# sau đó tôi cố gắng nhìn vào mã của tôi và tôi tìm thấy nơi mà vấn đề xảy ra:

Tôi có một phương pháp post ajax và khi tôi đăng dữ liệu có lỗi này nên dữ liệu tôi đã truyền sẽ được thu thập bằng phương pháp web C#, vì vậy khi tôi thấy mô hình đó tôi có 2 thuộc tính có cùng tên để tôi loại bỏ một vấn đề và ngoại lệ đã được giải quyết.