C#隐式转换

Chr*_*den 5 c# implicit-conversion

我目前正在开发一个应用程序,我需要从SQL数据库加载数据,然后将检索到的值分配给对象的属性.我这样做是通过使用反射,因为属性名称和列名称是相同的.但是,许多属性都使用自定义结构类型,它基本上是十进制类型的货币包装器.我在我的struct中定义了一个隐式转换:

public static implicit operator Currency(decimal d)
{
     return new Currency(d);
}
Run Code Online (Sandbox Code Playgroud)

我在代码中使用它时工作正常.但是,当我有这个:

foreach (PropertyInfo p in props)
{
     p.SetValue(this, table.Rows[0][p.Name], null);
}
Run Code Online (Sandbox Code Playgroud)

它抛出一个ArgumentException,声明它无法从System.Decimal转换为Currency.我很困惑,因为它在任何其他情况下都能正常工作.

Cha*_*lie 10

不幸的是,运行时不使用这些用户定义的转换运算符; 它们仅在编译时由编译器使用.因此,如果您采用强类型decimal并将其分配给强类型Currency,编译器将向您的转换运算符插入一个调用,并且每个人都很高兴.但是,当你SetValue在这里调用时,运行时期望你给它一个适当类型的值; 运行时不知道这个转换运算符是否存在,并且不会调用它.

  • 究竟.隐式转换类似于扩展方法和默认参数 - 编译器就是这样做的. (2认同)

Dan*_*Tao 3

认为您需要首先将值拆箱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);
     }
}
Run Code Online (Sandbox Code Playgroud)

这是我以前见过一两次的问题,所以我实际上决定写一篇关于它的博客文章。任何想要更多解释的人,请随时阅读。