c# - property - setvalue




Definindo uma propriedade por reflexão com um valor de string (8)

Eu gostaria de definir uma propriedade de um objeto através do Reflection, com um valor do tipo string . Então, por exemplo, suponha que eu tenha uma classe Ship , com uma propriedade do Latitude , que é um double .

Aqui está o que eu gostaria de fazer:

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

Como é, isso lança um ArgumentException :

Objeto do tipo 'System.String' não pode ser convertido para o tipo 'System.Double'.

Como posso converter o valor para o tipo adequado, com base no propertyInfo ?


Como vários outros disseram, você deseja usar o Convert.ChangeType :

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

Na verdade, eu recomendo que você olhe toda a classe Convert .

Esta classe e muitas outras classes úteis fazem parte do Namespace do System . Acho útil varrer esse namespace todo ano para ver quais recursos eu perdi. De uma chance!


Eu noto que muitas pessoas estão recomendando Convert.ChangeType - Isso funciona para alguns casos, no entanto, assim que você começar a envolver tipos nullable você começará a receber InvalidCastExceptions :

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

Um wrapper foi escrito há alguns anos para lidar com isso, mas isso também não é perfeito.

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


Eu vou responder isso com uma resposta geral. Normalmente, essas respostas não funcionam com guias. Aqui está uma versão de trabalho com guias também.

var stringVal="6e3ba183-89d9-e611-80c2-00155dcfb231"; // guid value as string to set
var prop = obj.GetType().GetProperty("FooGuidProperty"); // property to be setted
var propType = prop.PropertyType;

// var will be type of guid here
var valWithRealType = TypeDescriptor.GetConverter(propType).ConvertFrom(stringVal); 

Ou você poderia tentar:

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

//But this will cause problems if your string value IsNullOrEmplty...

Usando Convert.ChangeType e obtendo o tipo para converter do PropertyInfo.PropertyType .

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

Você está procurando brincar com o Reflection ou está procurando construir um software de produção? Eu questionaria por que você está usando reflexão para definir uma propriedade.

Double new_latitude;

Double.TryParse (value, out new_latitude);
ship.Latitude = new_latitude;

Você pode usar um conversor de tipo (sem verificação de erro):

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

Em termos de organizar o código, você poderia criar um tipo de mixin que resultaria em código como este:

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

Isto seria conseguido com este código:

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 pode ser reutilizado para muitas classes diferentes.

Você também pode criar seus próprios conversores de tipos personalizados para anexar às suas propriedades ou classes:

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

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

Você provavelmente está procurando o método Convert.ChangeType . Por exemplo:

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




setvalue