[英]C# implicit conversions
我目前正在开发一个应用程序,我需要从SQL数据库加载数据,然后将检索到的值分配给对象的属性。 我这样做是通过使用反射,因为属性名称和列名称是相同的。 但是,许多属性都使用自定义结构类型,它基本上是十进制类型的货币包装器。 我在我的struct中定义了一个隐式转换:
public static implicit operator Currency(decimal d)
{
return new Currency(d);
}
我在代码中使用它时工作正常。 但是,当我有这个:
foreach (PropertyInfo p in props)
{
p.SetValue(this, table.Rows[0][p.Name], null);
}
它抛出一个ArgumentException,声明它无法从System.Decimal转换为Currency。 我很困惑,因为它在任何其他情况下都能正常工作。
不幸的是,运行时不使用这些用户定义的转换运算符; 它们仅在编译时由编译器使用。 因此,如果您使用强类型decimal
并将其分配给强类型Currency
,编译器将向您的转换运算符插入一个调用,并且每个人都很高兴。 但是,当你在这里调用SetValue
时,运行时期望你给它一个适当类型的值; 运行时不知道这个转换运算符是否存在,并且不会调用它。
我想你需要首先将table.Rows[0][p.Name]
的值table.Rows[0][p.Name]
作为decimal
。
换一种说法:
foreach (PropertyInfo p in props)
{
if (p.PropertyType == typeof(Currency))
{
Currency c = (decimal)table.Rows[0][p.Name];
p.SetValue(this, c, null);
}
else
{
p.SetValue(this, table.Rows[0][p.Name], null);
}
}
这是我之前看过一两次的问题,所以我实际上决定写一篇关于它的博客文章 。 任何人都在寻找更多解释,随意给它一个阅读。
我假设该table
在您的代码table
是DataTable
类型,因此第一个索引器返回DataRow
,第二个索引器返回一个object
。 然后PropertyInfo.SetValue
也将一个object
作为第二个参数。 在此代码中没有地方铸造发生在代码 ,这就是为什么没有应用过载转换操作符。
一般来说,它仅在已知静态类型时才会应用(暂时忘记C#4.0中的dynamic
)。 装箱和拆箱时不适用。 在这种情况下, DataRow
上的索引器将该值设置为值,而PropertyInfo.SetValue
尝试将其拆分为其他类型 - 并且失败。
虽然我没有回答你的问题,但我认为在这种情况下使用像Entity Framework或NHibernate这样的ORM框架会更合适,它会将你的表映射到你的域对象并为你处理所有的转换。 使用像反射之类的东西来确定填写域对象的字段是一种缓慢的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.