为什么我使用虚拟或非虚拟属性获得不同的结果?

Ian*_*anR 9 .net c#

下面的代码,在.NET 4.5上运行发布配置时,会产生以下输出...

Without virtual: 0.333333333333333
With virtual:    0.333333343267441
Run Code Online (Sandbox Code Playgroud)

(在调试中运行时,两个版本都会给出0.333333343267441结果.)

我可以看到,将一个浮点除以一个short并将其返回一个double可能会在一个点之后产生垃圾.

我的问题是:任何人都能解释为什么在分母中提供短片的属性是虚拟的还是非虚拟的时,结果会有所不同?

public class ProvideThreeVirtually
{
    public virtual short Three { get { return 3; } }
}

public class GetThreeVirtually
{
    public double OneThird(ProvideThreeVirtually provideThree)
    {
        return 1.0f / provideThree.Three;
    }
}

public class ProvideThree
{
    public short Three { get { return 3; } }
}

public class GetThree
{
    public double OneThird(ProvideThree provideThree)
    {
        return 1.0f / provideThree.Three;
    }
}

class Program
{
    static void Main()
    {
        var getThree = new GetThree();
        var result = getThree.OneThird(new ProvideThree());

        Console.WriteLine("Without virtual: {0}", result);

        var getThreeVirtually = new GetThreeVirtually();
        var resultV = getThreeVirtually.OneThird(new ProvideThreeVirtually());

        Console.WriteLine("With virtual:    {0}", resultV);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ter*_*rni 0

我已经在 .Net 4.5 下测试了您的代码,
在 Visual Studio 2012 中运行时我总是得到相同的结果:
在 Rel/Dbg 32 位中运行时为
0.333333333333333 在 Rel/Dbg 64 位中运行时为 0.333333343267441

我在运行 exe 时得到结果,而无需从没有 Visual Studio 的提示符启动它,并且仅当代码为:

  • 在 64 位模式下运行(我在任何 CPU 中运行,并且代码是在没有首选 32 位检查的情况下编译的)
  • 发布中

优化代码选项没有任何区别。

我唯一能想到的是,使用 virtual 会强制稍后对 double 类型进行求值,因此运行时会使用浮点执行 1/3,然后将结果提升为 double,而在不使用虚拟属性时,它会将操作数直接提升为 double在进行操作之前