Dav*_*son 298 c# reflection type-conversion propertyinfo setvalue
我想通过Reflection设置对象的属性,值为type string
.所以,举个例子,假设我有Ship
一个属性为的类Latitude
,它是一个double
.
这是我想做的事情:
Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, value, null);
Run Code Online (Sandbox Code Playgroud)
这样就抛出了ArgumentException
:
"System.String"类型的对象无法转换为"System.Double"类型.
如何将值转换为正确的类型,基于propertyInfo
?
LBu*_*kin 506
您可以使用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);
Run Code Online (Sandbox Code Playgroud)
Joh*_*ers 34
正如其他几个人所说,你想要使用Convert.ChangeType
:
propertyInfo.SetValue(ship,
Convert.ChangeType(value, propertyInfo.PropertyType),
null);
Run Code Online (Sandbox Code Playgroud)
事实上,我建议你看看整个Convert
班级.
这个类和许多其他有用的类是System
Namespace的一部分.我发现每年扫描一个命名空间很有用,看看我错过了哪些功能.试试看!
Tab*_*let 19
我注意到很多人都在推荐Convert.ChangeType
- 这确实适用于某些情况但是一旦你开始涉及nullable
类型,你将开始接收InvalidCastExceptions
:
几年前写了一个封装器来处理这个问题,但这也不完美.
Jor*_*dão 11
您可以使用类型转换器(无错误检查):
Ship ship = new Ship();
string value = "5.5";
var property = ship.GetType().GetProperty("Latitude");
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);
Run Code Online (Sandbox Code Playgroud)
在组织代码方面,你可以创建一种mixin,它会产生如下代码:
Ship ship = new Ship();
ship.SetPropertyAsString("Latitude", "5.5");
Run Code Online (Sandbox Code Playgroud)
这将通过以下代码实现:
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; }
// ...
}
Run Code Online (Sandbox Code Playgroud)
MPropertyAsStringSettable
可以重复用于许多不同的类.
您还可以创建自己的自定义类型转换器以附加到您的属性或类:
public class Ship : MPropertyAsStringSettable {
public Latitude Latitude { get; set; }
// ...
}
[TypeConverter(typeof(LatitudeConverter))]
public class Latitude { ... }
Run Code Online (Sandbox Code Playgroud)
我尝试了LBushkin的答案并且效果很好,但它不适用于空值和可空字段.所以我把它改成了这个:
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);
}
Run Code Online (Sandbox Code Playgroud)
你可能正在寻找这种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);
Run Code Online (Sandbox Code Playgroud)
使用Convert.ChangeType
和获取转换类型PropertyInfo.PropertyType
.
propertyInfo.SetValue( ship,
Convert.ChangeType( value, propertyInfo.PropertyType ),
null );
Run Code Online (Sandbox Code Playgroud)
我会用一般性的答案来回答这个问题。通常这些答案不适用于 guid。这是一个带有 guid 的工作版本。
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);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
262085 次 |
最近记录: |