是否可以复制不安全的类字段

时间:2014-05-21 15:45:48

标签: c# unsafe

我有两个班级

[StructLayout(LayoutKind.Explicit, Size = 12, CharSet = CharSet.Ansi)]
unsafe class Dto
{
    [FieldOffset(0)]
    public int B;
    [FieldOffset(4)]
    public int C;
    [FieldOffset(8)]
    public int D;
}
[StructLayout(LayoutKind.Explicit, Size = 12, CharSet = CharSet.Ansi)]
unsafe class Model
{
    [FieldOffset(0)]
    public int B;
    [FieldOffset(4)]
    public int C;
    [FieldOffset(8)]
    public int D;
}

有没有办法从DTO模型实例的字段中复制数据? 对于单个字段,我有以下代码

var a1 = new Dto { B = 10, C = 20, D = 30 };
var a2 = new Model();

unsafe
{
     fixed (int* pa1 = &(a1.B))
     {
          fixed (int* pa2 = &(a2.B))
          {
               *pa2 = *pa1;
          }
     }
 }

C#是否提供了复制整个对象的类似方法?由于高性能环境,不希望逐个字段地复制。

2 个答案:

答案 0 :(得分:2)

您主要担心的是表现。如果您逐字段复制,则会转换为6 mov条指令。很难让它比这更快。

使用指针不会减少所需的指令数量。为什么会这样?你仍然需要相同的作业。

调用memcpy涉及的开销远远超过简单的6 mov指令。

所以你应该写一些"天真的"使用安全托管代码进行三次分配以获得最佳性能。事实上,复制这个12字节的对象是如此便宜,我怀疑你的性能问题是否有效。我怀疑这会出现在任何档案中。

对于复制效果,您使用class还是struct并不重要。但struct由于其他差异而具有一定的性能优势。您可能想要调查它们。

答案 1 :(得分:0)

C#中与memcpy最接近的是Buffer.BlockCopy,尽管它是为数组设计的。

这是关于该主题的interesting article

我认为,如果您要简化代码,删除不安全,只使用转换运算符的普通结构,您会对性能感到非常惊讶。

喜欢的东西;

   public struct Model
   {
      public int B;
      public int C;
      public int D;

      public Model(Dto dto)
      {
         B = dto.B;
         C = dto.C;
         D = dto.D;
      }

      static public implicit operator Model(Dto dto)
      {
         return new Model(dto);
      }
   }

允许你只说...

     Dto a1 = new Dto { B = 10, C = 20, D = 30 };

     Model m = a1;