2009-09-28 30 views
10

Tôi cố gắng đặt thuộc tính Nullable <> động.Đặt thuộc tính Nullable <> bằng cách phản chiếu

I Get cựu tài sản của tôi:

PropertyInfo property = class.GetProperty("PropertyName"); // My property is Nullable<> at this time So the type could be a string or int 

Tôi muốn thiết lập tài sản của tôi bằng cách phản chiếu như

property.SetValue(class,"1256",null); 

Nó không hoạt động khi tài sản của tôi là một Nullable <> Chung. Vì vậy, tôi cố gắng tìm một cách để thiết lập tài sản của tôi.

Để biết loại của tôi nullable <> tài sản i thực hiện

Nullable.GetUnderlyingType(property.PropertyType) 

Bất kỳ ý tưởng?

  • tôi Hãy cố gắng tạo một thể hiện của tôi Nullable <> tài sản với

    var nullVar = Activator.CreateInstance (typeof (Nullable <>). MakeGenericType (Type mới [] {Nullable.GetUnderlyingType (bất động sản .PropertyType)}));

Nhưng nullVar luôn là Null

+0

Tính năng này có hoạt động khi bạn đặt số nguyên thay vì chuỗi không? '" 1256 "' là một chuỗi, không phải là số nguyên. –

+0

Nó sẽ làm việc, nhưng quan điểm là tôi không biết loại tài sản nullable. Tôi có thể sử dụng Nullable.GetUnderlyingType (property.PropertyType) để có được kiểu –

+0

'Nullable <>' không thể sử dụng 'string' cho kiểu cơ bản là' string' là một kiểu tham chiếu. Nói cách khác 'typeof (Nullable <>). MakeGenericType (t);' sẽ ổn nếu 't == typeof (int)', nhưng nó sẽ phát nổ (ràng buộc không được đáp ứng) với 't == typeof (string)' . Vì vậy, 'Nullable <>' sẽ không có bất kỳ cách nào hoạt động như một loại "kiểu phổ biến" cho các kiểu tham chiếu và các kiểu giá trị rỗng. –

Trả lời

13

Nếu bạn muốn chuyển đổi một chuỗi tùy ý để loại cơ bản của Nullable, bạn có thể sử dụng lớp Convert:

var propertyInfo = typeof(Foo).GetProperty("Bar"); 
object convertedValue = null; 
try 
{ 
    convertedValue = System.Convert.ChangeType("1256", 
     Nullable.GetUnderlyingType(propertyInfo.PropertyType)); 
} 
catch (InvalidCastException) 
{ 
    // the input string could not be converted to the target type - abort 
    return; 
} 
propertyInfo.SetValue(fooInstance, convertedValue, null); 

Ví dụ này sẽ hoạt động nếu loại mục tiêu là int, ngắn, dài (hoặc các biến thể chưa ký, vì chuỗi đầu vào đại diện cho một số không âm), double, float hoặc decimal. Caveat: đây không phải là mã nhanh.

+0

Tôi sẽ thử rằng, tại thời điểm này tôi tink của bạn là câu trả lời gần hơn tôi tìm kiếm –

+0

Đó là workin Cảm ơn –

+0

Đó là làm việc cảm ơn bạn –

9

Nếu đó là một int nullable, bạn sẽ cần phải sử dụng một tham số int, không phải là một chuỗi.

property.SetValue(klass,1256,null); 

Lưu ý thay đổi thành klass, thay vì lớp học, vì lớp là từ khóa dành riêng. Bạn cũng có thể sử dụng @class nếu cần thiết (trích dẫn nó).

Nếu tài sản của bạn là một chung chung, thì tôi nghĩ bạn có thể sẽ cần phải sử dụng Chuyển đổi để chuyển đổi bất cứ điều gì bạn có bất cứ điều gì bạn cần.

var nullType = Nullable.GetUnderlyingType(property.PropertyType) 
var value = Convert.ChangeType("1256", nullType); 
property.SetValue(klass, value, null); 
+0

Tôi biết đó là một chuỗi nhưng đó là chung chung vì vậy tôi không biết những gì sẽ là loại. Nó chỉ là một ví dụ, gen của tôi Nullable <> có thể là một chuỗi, int một chuyển đổi chung sẽ được thực hiện –

+2

Bạn không thể có một 'Nullable ', vì 'chuỗi' không phải là một loại giá trị. –

2

"1256" là một chuỗi chứ không phải là int.

5

Đây là một ví dụ hoàn chỉnh cho thấy làm thế nào để làm điều đó:

using System; 
using System.Reflection; 

class Test 
{ 
    static void Main() 
    { 
     Foo foo = new Foo(); 
     typeof(Foo).GetProperty("Bar") 
      .SetValue(foo, 1234, null); 
    } 
} 

class Foo 
{ 
    public Nullable<Int32> Bar { get; set; } 
} 

Như những người khác đã đề cập đến bạn cần phải vượt qua đúng loại cho SetValue chức năng nhưng mã phản ánh khác của bạn không phải là hoàn toàn đúng một trong hai. Bạn cần phải có được loại của lớp trong câu hỏi trước khi bạn có thể truy vấn cho các thành viên của nó.

Chỉnh sửa: Nếu tôi hiểu chính xác bạn đang cố gắng đặt giá trị chuỗi cho bất kỳ thuộc tính nào thông qua phản ánh. Để làm điều này, bạn sẽ cần phải thực hiện một số loại kiểm tra và loại chuyển đổi.

Dưới đây là một ví dụ về những gì tôi có nghĩa là:

using System; 
using System.Reflection; 

class Test 
{ 
    static void Main() 
    { 
     Foo foo = new Foo(); 

     PropertyInfo property = typeof(Foo).GetProperty("Bar"); 
     Object value = 
      Convert.ChangeType("1234", 
       Nullable.GetUnderlyingType(property.PropertyType) 
       ?? property.PropertyType); 

     property.SetValue(foo, value, null); 
    } 
} 

class Foo 
{ 
    public Nullable<Int32> Bar { get; set; } 
} 

Cách tiếp cận này có thể được sử dụng một cách an toàn bất kể có hay không tài sản là Nullable<>.

2

Tôi nhấn cùng vấn đề này cũng như vấn đề với Convert.ChangeType không xử lý DateTimes trên Nullables vì ​​vậy tôi kết hợp một vài giải pháp ngăn xếp với một số phép thuật động .NET 4 để có được thứ mà tôi nghĩ là ngọt ngào. Nếu bạn nhìn vào mã, chúng ta sử dụng động để gõ đối tượng vào Nullable tại thời gian chạy, sau đó thời gian chạy xử lý nó một cách khác nhau và cho phép gán các kiểu cơ sở cho đối tượng nullable.

public void GenericMapField(object targetObj, string fieldName, object fieldValue) 
{ 
    PropertyInfo prop = targetObj.GetType().GetProperty(fieldName); 
    if (prop != null) 
    { 
     if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) 
     { 
      dynamic objValue = System.Activator.CreateInstance(prop.PropertyType); 
      objValue = fieldValue; 
      prop.SetValue(targetObj, (object)objValue, null); 
     } 
     else 
     { 
      prop.SetValue(targetObj, fieldValue, null); 
     } 
    } 
} 
0
public static void SetValue(object target, string propertyName, object value) 
{ 
    if (target == null) 
    return; 

    PropertyInfo propertyInfo = target.GetType().GetProperty(propertyName); 

    object convertedValue = value; 
    if (value != null && value.GetType() != propertyInfo.PropertyType) 
    { 
    Type propertyType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType; 
    convertedValue = Convert.ChangeType(value, propertyType); 
    } 

    propertyInfo.SetValue(target, convertedValue, null); 
} 
Các vấn đề liên quan