Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将字节数组转换为对象_C# - Fatal编程技术网

C# 将字节数组转换为对象

C# 将字节数组转换为对象,c#,C#,在C#中有没有办法将普通字节数组转换为对象 e、 g鉴于这一类别: class Data { public int _int1; public int _int2; public short _short1; public long _long1; } 我希望基本上能够做这样的事情: var bytes = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0 }; var obj =

在C#中有没有办法将普通字节数组转换为对象

e、 g鉴于这一类别:

class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;
}
我希望基本上能够做这样的事情:

var bytes = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0 };
var obj = (Data)bytes;
使用方法。您只需指定起始索引,如下所示:

Data data = new Data();
data._int1 = BitConverter.ToInt32(bytes, 0);
data._int2 = BitConverter.ToInt32(bytes, 4);
data._short1 = BitConverter.ToInt16(bytes, 8);
data._long1 = BitConverter.ToInt64(bytes,10);
记住:

数组中字节的顺序必须反映 计算机系统结构

使用方法。您只需指定起始索引,如下所示:

Data data = new Data();
data._int1 = BitConverter.ToInt32(bytes, 0);
data._int2 = BitConverter.ToInt32(bytes, 4);
data._short1 = BitConverter.ToInt16(bytes, 8);
data._long1 = BitConverter.ToInt64(bytes,10);
记住:

数组中字节的顺序必须反映 计算机系统结构


没有什么可以一次性完成转换

但您可以在以下基础上进行构建:


没有什么可以一次性完成转换

但您可以在以下基础上进行构建:


您可以尝试编组:

将类的布局声明为顺序布局(请注意,您需要使用
Pack=1
):

将字节封送到数据类的新实例中:

var bytes = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0 };
GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
gcHandle.Free();

// Now data should contain the correct values.

Console.WriteLine(data._int1);    // Prints 1
Console.WriteLine(data._int2);    // Prints 2
Console.WriteLine(data._short1);  // Prints 3
Console.WriteLine(data._long1);   // Prints 4
为方便起见,您可以在数据上编写一个静态方法来进行转换:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;

    public static Data FromBytes(byte[] bytes)
    {
        GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
        gcHandle.Free();
        return data;
    }
}

...

var data = Data.FromBytes(new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0});
如果您真的想,您可以编写一个显式运算符,从字节数组转换,以获取OP中的语法。我建议只使用
Data.FromBytes()
,这在我看来会更清楚

不过,为了完整起见:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;

    public static explicit operator Data(byte[] bytes)
    { 
        GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
        gcHandle.Free();
        return data;
    }
}

...

var data = (Data)new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0};

您可以尝试编组:

将类的布局声明为顺序布局(请注意,您需要使用
Pack=1
):

将字节封送到数据类的新实例中:

var bytes = new byte[] { 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0 };
GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
gcHandle.Free();

// Now data should contain the correct values.

Console.WriteLine(data._int1);    // Prints 1
Console.WriteLine(data._int2);    // Prints 2
Console.WriteLine(data._short1);  // Prints 3
Console.WriteLine(data._long1);   // Prints 4
为方便起见,您可以在数据上编写一个静态方法来进行转换:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;

    public static Data FromBytes(byte[] bytes)
    {
        GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
        gcHandle.Free();
        return data;
    }
}

...

var data = Data.FromBytes(new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0});
如果您真的想,您可以编写一个显式运算符,从字节数组转换,以获取OP中的语法。我建议只使用
Data.FromBytes()
,这在我看来会更清楚

不过,为了完整起见:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class Data
{
    public int _int1;
    public int _int2;
    public short _short1;
    public long _long1;

    public static explicit operator Data(byte[] bytes)
    { 
        GCHandle gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        var data = (Data)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(Data));
        gcHandle.Free();
        return data;
    }
}

...

var data = (Data)new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0};

下面是一种将字节数组转换为对象的方法

var binaryFormatter = new BinaryFormatter();
using (var ms = new MemoryStream(bytes))
{
    object obj = binaryFormatter.Deserialize(ms);
    return (Data)obj;
}

下面是一种将字节数组转换为对象的方法

var binaryFormatter = new BinaryFormatter();
using (var ms = new MemoryStream(bytes))
{
    object obj = binaryFormatter.Deserialize(ms);
    return (Data)obj;
}

你想要实现什么?在字节与要创建的实例之间的关系中必须有一些登录名。从技术上讲,您可以实现一个运算符,即
公共静态显式运算符数据(字节[]源){…}
但序列化是更好的解决方案。了解一些情况-看起来您正在尝试读取从某些C/C++结构编写的数据。是这样吗?谢谢你的评论,我知道我可以使用BitConverter分别转换每个成员,我不能反序列化,因为数据一开始不是序列化的,它只是原始数据。它可以用C++来做,只是说我知道这一块数据真的是这个结构,把它当作这样的,但是也许你不能在C语言中这么容易地做。你想要达到什么?在字节与要创建的实例之间的关系中必须有一些登录名。从技术上讲,您可以实现一个运算符,即
公共静态显式运算符数据(字节[]源){…}
但序列化是更好的解决方案。了解一些情况-看起来您正在尝试读取从某些C/C++结构编写的数据。是这样吗?谢谢你的评论,我知道我可以使用BitConverter分别转换每个成员,我不能反序列化,因为数据一开始不是序列化的,它只是原始数据。它可以在C++中完成,只是说我知道这一块数据是真的这个结构,把它当作这样,但是你可能不能在C很容易做到这一点。@ OguzOzgul完全不真实。谢谢,我想这是最好的答案。关于使用big-endian的系统呢?@Geograph你必须确保字节是正确的。(OP是在与C++的相同效果之后)。谢谢,我想这是最好的答案。关于使用big-endian的系统呢?@Geograph你必须确保字节是正确的。(OP是在与C++ CAST相同的效果之后)。