繁体   English   中英

C#隐式转换

[英]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在您的代码tableDataTable类型,因此第一个索引器返回DataRow ,第二个索引器返回一个object 然后PropertyInfo.SetValue也将一个object作为第二个参数。 在此代码中没有地方铸造发生在代码 ,这就是为什么没有应用过载转换操作符。

一般来说,它仅在已知静态类型时才会应用(暂时忘记C#4.0中的dynamic )。 装箱和拆箱时不适用。 在这种情况下, DataRow上的索引器将该值设置为值,而PropertyInfo.SetValue尝试将其拆分为其他类型 - 并且失败。

虽然我没有回答你的问题,但我认为在这种情况下使用像Entity Framework或NHibernate这样的ORM框架会更合适,它会将你的表映射到你的域对象并为你处理所有的转换。 使用像反射之类的东西来确定填写域对象的字段是一种缓慢的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM