2010-06-15 26 views
10

Nếu tôi có một cái gì đó như:PropertyInfo SetValue và null

object value = null; 
Foo foo = new Foo(); 

PropertyInfo property = Foo.GetProperties().Single(p => p.Name == "IntProperty"); 
property.SetValue(foo, value, null); 

Sau đó foo.IntProperty được thiết lập để 0, mặc dù value = null. Dường như nó đang làm một cái gì đó như IntProperty = default(typeof(int)). Tôi muốn ném một số InvalidCastException nếu IntProperty không phải là loại "không thể sử dụng" (Nullable<> hoặc tham chiếu). Tôi đang sử dụng Reflection, vì vậy tôi không biết loại trước thời hạn. Tôi sẽ đi đâu để tới đó?

Trả lời

12

Nếu bạn có số PropertyInfo, bạn có thể kiểm tra .PropertyType; nếu .IsValueType là đúng, và nếu Nullable.GetUnderlyingType(property.PropertyType) là null, sau đó nó là một giá trị kiểu nullable:

 if (value == null && property.PropertyType.IsValueType && 
      Nullable.GetUnderlyingType(property.PropertyType) == null) 
     { 
      throw new InvalidCastException(); 
     } 
+0

Vậy đó. Tôi đã rối tung với .PropertyType.IsClass, nhưng đã không nhận được rất xa. –

1

Bạn có thể sử dụng PropertyInfo.PropertyType.IsAssignableFrom biểu thức (value.GetType()) để xác định xem giá trị quy định có thể được viết vào tài sản. Nhưng bạn cần phải xử lý trường hợp khi giá trị là null, vì vậy trong trường hợp này bạn có thể gán nó vào tài sản duy nhất nếu loại tài sản là nullable hoặc loại tài sản là loại tài liệu tham khảo:

public bool CanAssignValueToProperty(PropertyInfo propertyInfo, object value) 
{ 
    if (value == null) 
     return Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null || 
       !propertyInfo.IsValueType; 
    else 
     return propertyInfo.PropertyType.IsAssignableFrom(value.GetType()); 
} 

Ngoài ra, bạn có thể tìm thấy Convert.ChangeType hữu ích để viết giá trị chuyển đổi thành thuộc tính.

+0

SetValue() đã ném một ngoại lệ khi nó không thể đặt giá trị, đó là hành vi mong muốn (nhưng nó là một ArgumentException). Tôi chỉ cần xử lý kịch bản null. –

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