【问题标题】:Generic decimal can't cast from double通用小数不能从双精度转换
【发布时间】:2016-09-20 18:29:58
【问题描述】:

我不明白为什么这不起作用,我可以从double 直接转换为decimal 没有问题,但出乎意料的是,如果它在泛型类中,我无法进行此转换,这sn-p 解释得更好:

public class TestCollection<T>
{
    public void Add(object value)
    {
        //When T is decimal, then I get 
        // System.InvalidCastException
        var t = (T) value;
    }
}

public void Main ()
{
    var t = new TestCollection<decimal> ();
    double doub = 10;

    var decim = (decimal) doub; //Works!       
    t.Add(doub);                //throws!
}

System.InvalidCastException 未被用户代码处理 H结果=-2147467262 Message=指定的强制转换无效。 来源=Wpf 堆栈跟踪: 在 Wpf.TestCollection`1.Add(Object value) in C:\Users\btord\Source\Repos\Live-Charts\Examples\Wpf\JimmyTheTestsGuy.xaml.cs:line 15 在 C:\Users\btord\Source\Repos\Live-Charts\Examples\Wpf\JimmyTheTestsGuy.xaml.cs:line 35 中的 Wpf.JimmyTheTestsGuy..ctor() 在 C:\Users\btord\Source\Repos\Live-Charts\Examples\Wpf\MainWindow.xaml.cs:line 56 中的 Wpf.MainWindow..ctor() 内部异常:

【问题讨论】:

  • 发生这种情况是因为您传递了对象,而不是双倍。
  • 为什么类型是value object 而不是T
  • @Lee 我有2个重载,一个用于T,一个用于对象,调用对象重载时出现错误,这是代码的一小部分

标签: c# generics casting


【解决方案1】:

由于以下失败的完全相同的原因而失败:

short s = 1;
object o = s;
var i = (int)o; //Runtime error

原因是一个装箱的值只能拆箱到它的真实类型。在您的情况下,您正在装箱 double 并尝试将其拆箱到 decimal。这是不允许的。

我会推迟整个设计。你有一个通用的Ts 集合。您的 Add 方法应该简单地接受 Ts 并让调用者承担转换为正确类型的负担。如果这不是一个有效的解决方案,那么就一起摆脱泛型并简单地实现一个对象集合。

【讨论】:

  • @bto.rdz public void Add(dynamic value) 似乎可以工作,如果你对dynamic 没意见的话。
【解决方案2】:

您可以为此使用Convert.ChangeType

public void Add(object value)
{
    var t = Convert.ChangeType(value, typeof(T));
}

见小提琴:https://dotnetfiddle.net/0Tfgyz

【讨论】:

  • 谢谢,我担心这种方法的性能,因为这种方法在我的代码中非常重要
  • 好的。也许您应该先对其进行分析,看看是否可行。刚刚找到一个处理ChangeType 性能的stackoverflow 答案:stackoverflow.com/questions/1532197/…
【解决方案3】:

如果您需要 T 以外的对象,您可以在 Add 方法中使用 dynamic。

 public void Add(object value)
 {
      //When T is decimal, then I get 
      // System.InvalidCastException
      dynamic t1 = value;
      var t = (T)t1;
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 2015-09-13
    相关资源
    最近更新 更多