2012-03-31 33 views
65

Tôi có một đối tượng kiểu ẩn danh mà tôi nhận được dưới dạng động từ một phương thức Tôi muốn kiểm tra trong một thuộc tính tồn tại trên đối tượng đó.Làm cách nào để kiểm tra xem thuộc tính có tồn tại trên loại ẩn danh động trong C# không?

.... 
var settings = new { 
        Filename="temp.txt", 
        Size=10 
} 
... 

function void Settings(dynamic settings) { 
var exists = IsSettingExist(settings,"Filename") 
} 

Làm cách nào để triển khai IsSettingExist?

+2

có thể trùng lặp của [Làm thế nào để phát hiện nếu một tài sản tồn tại trên một ExpandoObject?] (Http://stackoverflow.com/questions/2839598/how-to-detect-if-a-property-exists-on -an-expandoobject) – Sebastian

Trả lời

92
public static bool IsPropertyExist(dynamic settings, string name) 
    { 
    if (settings is ExpandoObject) 
     return ((IDictionary<string, object>)settings).ContainsKey(name); 

    return settings.GetType().GetProperty(name) != null; 
    } 

    var settings = new {Filename = @"c:\temp\q.txt"}; 
    Console.WriteLine(IsPropertyExist(settings, "Filename")); 
    Console.WriteLine(IsPropertyExist(settings, "Size")); 

Output:

True 
False 
+11

Điều này không hoạt động trong mọi trường hợp: http://stackoverflow.com/a/11540889/238419 –

+1

Điều này không hoạt động trên các đối tượng động. Nó luôn trả về null. – evilom

+0

Điều này không hoạt động. –

11

nếu bạn có thể kiểm soát việc tạo/chuyển đối tượng cài đặt, tôi khuyên bạn nên sử dụng ExpandoObject thay thế.

dynamic settings = new ExpandoObject(); 
settings.Filename = "asdf.txt"; 
settings.Size = 10; 
... 

function void Settings(dynamic settings) 
{ 
    if (((IDictionary<string, object>)settings).ContainsKey("Filename")) 
     .... do something .... 
} 
+0

Tôi không thể thay đổi, tôi có thể truyền sang ExpendoObject không? –

25
public static bool HasProperty(dynamic obj, string name) 
{ 
    Type objType = obj.GetType(); 

    if (objType == typeof(ExpandoObject)) 
    { 
     return ((IDictionary<string, object>)obj).ContainsKey(name); 
    } 

    return objType.GetProperty(name) != null; 
} 
+0

'objType.GetProperty (name)! = Null;' trả về null trên các thuộc tính tồn tại –

+1

'objType.GetProperty (name)! = Null' sẽ luôn trả về một 'bool', mà (theo định nghĩa) không bao giờ có thể là' null'. –

+0

@AlexMcMillan Không chắc chắn kích thước bạn sống ở đâu 'Loại.GetProperty (chuỗi)' cho một tài sản không tồn tại trả về bất cứ điều gì khác hơn là null. –

3

này đang làm việc cho ME:

public static bool IsPropertyExist(dynamic dynamicObj, string property) 
     { 
      try 
      { 
       var value=dynamicObj[property].Value; 
       return true; 
      } 
      catch (RuntimeBinderException) 
      { 

       return false; 
      } 

     } 
+10

Cho phép ngoại lệ xảy ra và sau đó đánh bắt chúng không phải là giải pháp ưu tiên vì có rất nhiều chi phí liên quan đến việc ném và bắt. Đó là một phương sách cuối cùng mà thôi. Các ngoại lệ được thiết kế cho các tình huống mà * sẽ * không xảy ra trong quá trình thực hiện như mạng không khả dụng. Có nhiều giải pháp tốt hơn ở đây. –

+0

Không có 'RuntimeBinderException' và' dynamicObj [property] .Value' khi giá trị thực sự ở đó ... 'var value = dynamicObj [property]' là đủ ... và khi nó không tồn tại 'KeyNotFoundException' trên 'Dictionary' bị ném ... xem bên dưới ... –

0

dùng phản ánh, đây là chức năng tôi sử dụng:

public static bool doesPropertyExist(dynamic obj, string property) 
{ 
    return ((Type)obj.GetType()).GetProperties().Where(p => p.Name.Equals(property)).Any(); 
} 

sau đó ..

if (doesPropertyExist(myDynamicObject, "myProperty")){ 
    // ... 
} 
1

Không ai trong số các giải pháp trên làm việc cho dynamic đến từ Json, tôi tuy nhiên quản lý để chuyển đổi một với Try catch (bởi @ user3359453) bằng cách thay đổi kiểu ngoại lệ ném (KeyNotFoundException thay vì RuntimeBinderException) vào một cái gì đó thực sự hoạt động ...

public static bool HasProperty(dynamic obj, string name) 
    { 
     try 
     { 
      var value = obj[name]; 
      return true; 
     } 
     catch (KeyNotFoundException) 
     { 
      return false; 
     } 
    } 

enter image description here

Hy vọng điều này sẽ giúp bạn tiết kiệm thời gian.

+1

cái này làm việc cho tôi. Cảm ơn bạn! – Carlos

1

Hợp nhất và sửa câu trả lời từ Serj-TM và user3359453 để nó hoạt động với cả ExpandoObject và DynamicJsonObject. Điều này làm việc cho tôi.

public static bool HasPropertyExist(dynamic settings, string name) 
{ 
    if (settings is System.Dynamic.ExpandoObject) 
     return ((IDictionary<string, object>)settings).ContainsKey(name); 

    if (settings is System.Web.Helpers.DynamicJsonObject) 
    try 
    { 
     return settings[name] != null; 
    } 
    catch (KeyNotFoundException) 
    { 
     return false; 
    } 


    return settings.GetType().GetProperty(name) != null; 
} 
0

này hoạt động với nhiều loại vô danh, ExpandoObject, Nancy.DynamicDictionary hoặc bất cứ điều gì khác mà có thể được đúc để IDictionary<string, object>.

public static bool PropertyExists(dynamic obj, string name) { 
     if (obj == null) return false; 
     if (obj is IDictionary<string, object> dict) { 
      return dict.ContainsKey(name); 
     } 
     return obj.GetType().GetProperty(name) != null; 
    } 
Các vấn đề liên quan