c# - 拳击,你喜欢什么,你认为哪个更快?

标签 c# word-wrap boxing

简而言之,我认为拳击是一种烦恼。让我们看看一些替代方案...

public class Box<T> 
    where T : struct
{
    public T Value { get; set; }

    public static implicit operator T(Box<T> box)
    {
        return box.Value;
    }
}

System.Int32 派生自抽象类 System.ValueType,后者派生自类 System.Object。您不能在 C# 中从 System.ValueType 派生,但我猜想 struct 关键字正是这样做的,并且 CLI 将这些类型定义识别为具有按值传递语义。无论如何,当将结构分配给对象类型时,就会发生装箱。我不想陷入拳击本身,而是想直接进入。

我查看了 C# 编译器生成的一些 IL。

object obj = 1;

.locals init ([0] object obj)
L_0000: nop 
L_0001: ldc.i4.1 
L_0002: box int32 // Convert a value type (of the type specified in valTypeToken) to a true object reference. 
L_0007: stloc.0 

在 MSDN 上找到这个...

值类型在公共(public)语言基础设施 (CLI) 中有两种独立的表示形式:

  • 当值类型嵌入到另一个对象或堆栈中时使用的“原始”形式。

  • 一种“装箱”形式,其中值类型中的数据被包装(装箱)到一个对象中,因此它可以作为一个独立的实体存在。

这让我得出结论,编写这样的代码应该同样昂贵......

var box = obj as Box<int>;
if (box != null)
{
    Console.WriteLine(box.Value);
}

如果我打算传递与 System.Object 相同的值,我真的想每次都对 ValueType 进行拆箱和装箱吗?我的直觉告诉我不,但我真的找不到好的动机有人愿意对所有这些喋喋不休发表评论吗?

编辑

有人曾经发现自己这样做过吗?我意识到这可能看起来很奇怪,但有一次我发现自己处于一个位置,我想根据几种不同的表示来抽象计算。我是这样做的,并且使用了 lambda 表达式。它与装箱并没有真正的关系,但它让我可以将任何 ValueType(该结构方便地对齐 8 字节)视为一种单一类型“ReinterpretCast”。

[StructLayout(LayoutKind.Explicit)]
public struct ReinterpretCast
{
    [FieldOffset(0)] sbyte @sbyte;
    [FieldOffset(0)] byte @byte;
    [FieldOffset(0)] short @ushort;
    [FieldOffset(0)] ushort @short;
    [FieldOffset(0)] int @int;
    [FieldOffset(0)] uint @uint;
    [FieldOffset(0)] long @long;
    [FieldOffset(0)] ulong @ulong;
    [FieldOffset(0)] float @float;
    [FieldOffset(0)] double @double;
}

最佳答案

我不是很确定你的问题。您只是在问您的解决方案是否比普通拳击更好?它当然有一些吸引力。如果您问为什么装箱最初没有以这种方式实现,请记住 .NET 没有泛型作为起点。

编辑:不管怎样,装箱对于泛型来说是相对少见的。不要忘记,如果对您的类型的实例的引用作为 object 传递(对于装箱来说通常是这种情况),您仍然必须执行运行时转换。也不要忘记接口(interface)——如果一个值类型实现了一个接口(interface),那么它对应的用于装箱的引用类型也是如此。您的解决方案不会删除装箱的使用,因为您不能让您的类型“假装”实现接口(interface)。 (您也许可以使用 DLR 做一些事情,但到那时大部分要点已经丢失了:)

关于c# - 拳击,你喜欢什么,你认为哪个更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/533379/

相关文章:

c# - HttpCookieCollection.Get() : Possible NullReferenceException

c# - 从 C# 中的字符串中删除空格?

c# - 使用 protobuf-net 将自定义类序列化为原始类型

c - 如何使用特定的定界符进行自动换行,而不进行动态分配

c# - 比较不同类型的装箱值

c# - 名称相似的T类型和非T类型方法的执行顺序?

c# - 如何在 Asp.Net 网站中包含另一个项目控制台应用程序 exe?

html - 将文本环绕成一个圆圈

html - CSS break-word 首先使用符号

java - 在 Java 中实现基本类型类型安全的最高效方法?