문자열 값으로 리플렉션하여 속성 설정 일은 다음과 같습니다. Ship ship = new

Reflection을 통해 객체의 속성을 값 유형으로 설정하고 싶습니다 string. 예를 들어 Ship속성 이 인 클래스 가 있다고 가정 Latitude합니다 double.

내가하고 싶은 일은 다음과 같습니다.

Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, value, null);

있는 그대로 이것은 다음을 발생시킵니다 ArgumentException.

‘System.String’유형의 오브젝트는 ‘System.Double’유형으로 변환 할 수 없습니다.

에 따라 값을 올바른 유형으로 변환하는 방법은 propertyInfo무엇입니까?



답변

당신은 사용할 수 있습니다 Convert.ChangeType()-그것은 당신이 어떤 런타임 정보를 사용할 수 있습니다IConvertible 유형의 하여 표시 형식을 변경할 수 있습니다. 그러나 모든 변환이 가능한 것은 아니며, 그렇지 않은 유형의 변환을 지원하려면 특수한 경우 논리를 작성해야 할 수도 있습니다 IConvertible.

해당 코드 (예외 처리 또는 특수 사례 논리 제외)는 다음과 같습니다.

Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);


답변

다른 사람들이 말했듯이 다음을 사용하고 싶습니다 Convert.ChangeType.

propertyInfo.SetValue(ship,
    Convert.ChangeType(value, propertyInfo.PropertyType),
    null);

사실, 나는 전체 ConvertClass 를 보는 것이 좋습니다 .

이 클래스와 다른 많은 유용한 클래스는 System네임 스페이스의 일부입니다 . 매년 해당 네임 스페이스를 스캔하여 놓친 기능을 확인하는 것이 유용하다는 것을 알았습니다. 시도 해봐!


답변

많은 사람들이 추천하고 있음을 알았습니다 Convert.ChangeType-일부 경우에는 작동하지만 nullable유형을 시작하자마자 수신을 시작합니다 InvalidCastExceptions.

http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx

래퍼는 몇 년 전에 이것을 처리하기 위해 작성되었지만 완벽하지는 않습니다.

http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx


답변

LBushkin 에서 답을 시도했지만 훌륭하게 작동했지만 null 값과 nullable 필드에는 작동하지 않습니다. 그래서 이것을 다음과 같이 변경했습니다.

propertyName= "Latitude";
PropertyInfo propertyInfo = ship.GetType().GetProperty(propertyName);
if (propertyInfo != null)
{
     Type t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
     object safeValue = (value == null) ? null : Convert.ChangeType(value, t);
     propertyInfo.SetValue(ship, safeValue, null);
}


답변

유형 변환기를 사용할 수 있습니다 (오류 검사 없음).

Ship ship = new Ship();
string value = "5.5";
var property = ship.GetType().GetProperty("Latitude");
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);

코드 구성 측면 에서 다음과 같은 코드를 생성하는 일종의 믹스 인 을 만들 수 있습니다 .

Ship ship = new Ship();
ship.SetPropertyAsString("Latitude", "5.5");

이것은이 코드로 달성 될 것입니다 :

public interface MPropertyAsStringSettable { }
public static class PropertyAsStringSettable {
  public static void SetPropertyAsString(
    this MPropertyAsStringSettable self, string propertyName, string value) {
    var property = TypeDescriptor.GetProperties(self)[propertyName];
    var convertedValue = property.Converter.ConvertFrom(value);
    property.SetValue(self, convertedValue);
  }
}

public class Ship : MPropertyAsStringSettable {
  public double Latitude { get; set; }
  // ...
}

MPropertyAsStringSettable 많은 다른 클래스에 재사용 할 수 있습니다.

속성 또는 클래스에 연결할 고유 한 사용자 지정 형식 변환기 를 만들 수도 있습니다 .

public class Ship : MPropertyAsStringSettable {
  public Latitude Latitude { get; set; }
  // ...
}

[TypeConverter(typeof(LatitudeConverter))]
public class Latitude { ... }


답변

아마도 Convert.ChangeType방법을 찾고있을 것입니다 . 예를 들면 다음과 같습니다.

Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);


답변

사용 Convert.ChangeType하고 변환하는 유형을 받고 PropertyInfo.PropertyType.

propertyInfo.SetValue( ship,
                       Convert.ChangeType( value, propertyInfo.PropertyType ),
                       null );