2

如果必须将值类型传递给方法,但由于某种原因,它必须作为引用类型传递,是否更快:

  1. 通过它作为object
  2. 通行证是作为ValueType
  3. 将其作为通用包装器传递

我在下面放了一些示例代码来说明我的意思:

public class Program
{
    public void Main()
    {
        var client = new IncrementedValueGetter();
        int i = 8675309;
        var byObject = client.IncrementObject(i);
        var byValueType = client.IncrementValueType(i);
        var byWrapper = client.IncrementWrapped(new ValueWrapper<int>(i));
    }
}
public class IncrementedValueGetter
{
    public int IncrementObject(object boxedValue)
    {
        return ((int)boxedValue) + 1;
    }
    public int IncrementValueType(ValueType boxedValueType)
    {
        return ((int) boxedValueType) + 1;
    }
    public int IncrementWrapped(ValueWrapper<int> valueWrapper)
    {
        return valueWrapper.Value + 1;
    }
}
public class ValueWrapper<T> 
    where T: struct
{
    private readonly T _value;
    public ValueWrapper(T value)
    {
        _value = value;
    }

    public T Value
    {
        get { return _value; }
    }
}
4

2 回答 2

4

前两个实际上是等价的,只是生成标准的boxIL。第三个需要构建你的包装类,这可能比盒子调用更昂贵。

于 2011-05-13T02:33:40.227 回答
1

这三者的性能可能相当,因为最终值类型必须以引用类型表示,这意味着在某些时候装箱。但是您可以通过不必要的开销和包装使事情变得更糟。

关于装箱的重要一点是它本身并不昂贵,它只是在特定的情况下相对昂贵,例如在紧密循环中装箱和拆箱。尝试关注为什么不能使用值类型本身以及为什么需要使用引用类型,并让它指导你的设计。您希望如何从引用类型访问值类型。引用类型会包含其他引用类型吗?等等。

最重要的是,如果您真的很担心,只需将其编码并测量即可。如果它对性能至关重要,并且您的应用程序不断发展,请继续在您的应用程序的上下文中对其进行测量。

于 2011-05-13T02:41:23.670 回答