C#将浮点数组强制转换为浮点结构

C#将浮点数组强制转换为浮点结构,c#,arrays,struct,casting,C#,Arrays,Struct,Casting,我在C#中有一个存储数据的浮点数组。但是,我需要将数据强制转换为Vector2、Vector3等结构。这些结构只包含浮点数,因此在字节方面没有数据类型转换,只有在access中 例如: 我可以通过创建一个新数组手动将整个float数组复制到struct-one,但对于大型数组来说,这有点慢。我曾尝试在不安全的代码中进行转换,但使用泛型不起作用,为我拥有的每个结构创建特殊方法有点“怪异” 在C++中,我有这样的事情: float * arrayFloat = .... Vector3 * arra

我在C#中有一个存储数据的浮点数组。但是,我需要将数据强制转换为Vector2、Vector3等结构。这些结构只包含浮点数,因此在字节方面没有数据类型转换,只有在access中

例如:

我可以通过创建一个新数组手动将整个float数组复制到struct-one,但对于大型数组来说,这有点慢。我曾尝试在不安全的代码中进行转换,但使用泛型不起作用,为我拥有的每个结构创建特殊方法有点“怪异”

在C++中,我有这样的事情:

float * arrayFloat = ....
Vector3 * arrayVector3 = reinterpret_cast<Vector3 *>(arrayFloat);
float*arrayFloat=。。。。
Vector3*arrayVector3=重新解释投射(arrayFloat);
但这在C#中不是一个选项


如何实现这一点,或者如何更改设计?您可以在结构中添加构造函数:

struct Vector3
{
   public float x;
   public float y;
   public float z;

   public Vector3(float[] vals)
   {
      if(vals.Length != 3)
         throw new ArgumentException();
      x = vals[0]; y = vals[1]; z = vals[2];
   }
}
……其他地方

float[] myFloats = { 0.0f, 1.1f, 2.2f };
var myVec = new Vector3(myFloats);

如果你问是否有什么东西可以让你不用做任何工作就可以做到这一点,答案是否定的。从数组到你选择的结构的任何转换都必须由你来实现,最好是在你的结构中实现。

你可以在结构中添加构造函数:

struct Vector3
{
   public float x;
   public float y;
   public float z;

   public Vector3(float[] vals)
   {
      if(vals.Length != 3)
         throw new ArgumentException();
      x = vals[0]; y = vals[1]; z = vals[2];
   }
}
……其他地方

float[] myFloats = { 0.0f, 1.1f, 2.2f };
var myVec = new Vector3(myFloats);
如果你问是否有什么东西可以让你不用做任何工作就可以做到这一点,答案是否定的。从数组到你选择的结构的任何转换都必须由你来实现,最好是在你的结构中实现。

我是C#新手,我也遇到过同样的问题,我发现有用的是使用一个枚举器,该枚举器在访问时惰性地转换每个元素:

IEnumerator<Vector3> Positions()
{
    for (int i = 0; i < _positions.Length / 3; ++i)
    {
        yield return new Vector3(_positions[3*i],
                                 _positions[3*i+1],
                                 _positions[3*i+2]);
    }
}
IEnumerator位置()
{
对于(int i=0;i<_positions.Length/3;++i)
{
产生返回新向量3(_位置[3*i],
_职位[3*i+1],
_职位[3*i+2]);
}
}
这样,您就不需要复制整个数组,编译器很可能不会在内存中创建类型为
Vector3
的新对象,而是使用寄存器。

我是C#新手,我也遇到了同样的问题,我发现使用枚举器很有用,它可以在访问时惰性地转换每个元素:

IEnumerator<Vector3> Positions()
{
    for (int i = 0; i < _positions.Length / 3; ++i)
    {
        yield return new Vector3(_positions[3*i],
                                 _positions[3*i+1],
                                 _positions[3*i+2]);
    }
}
IEnumerator位置()
{
对于(int i=0;i<_positions.Length/3;++i)
{
产生返回新向量3(_位置[3*i],
_职位[3*i+1],
_职位[3*i+2]);
}
}

有了它,您不需要复制整个数组,编译器很可能不会在内存中创建新的
Vector3
类型的对象,而是使用寄存器。

我相信这可以用于您的结构,使用.NET Core 2.1的
MemoryMarshal
方法

我的回答描述了如何。其实质是:

var vectors = MemoryMarshal.Cast<float, Vector3>(floatArray.AsSpan());
var firstVector = vectors[0];
var vectors=MemoryMarshal.Cast(floatArray.AsSpan());
var firstVector=向量[0];

这相当于C#的重新解释转换。

我相信,使用.NET Core 2.1的
MemoryMarshal
方法,这可以用于您的结构

我的回答描述了如何。其实质是:

var vectors = MemoryMarshal.Cast<float, Vector3>(floatArray.AsSpan());
var firstVector = vectors[0];
var vectors=MemoryMarshal.Cast(floatArray.AsSpan());
var firstVector=向量[0];

<>这是C的等价重铸。

在C++中我有这样的事情:“不,你不,这违反了严格的别名。(还有填充,以及乌布可能会遇到的任何其他味道)。我有C++结构,填充填充对齐,在MSVC编译器下应该是“安全的”,为什么不在“代码> VCARD2 2/代码>中存储数组,<代码>向量3>代码>……类而不是三个
double
值?然后,你只需要将给定的数组的“内部代码”设置为“代码> VC++ 3/CODE”,而不会发生复制。如果他的结构中包含数组,每个数组都需要堆分配,并且数组本身比这个紧凑的结构带来了相当多的内存开销。这违反了严格的别名。(还有填充,以及乌布可能会遇到的任何其他味道)。我有C++结构,填充填充对齐,在MSVC编译器下应该是“安全的”,为什么不在“代码> VCARD2 2/代码>中存储数组,<代码>向量3>代码>……类而不是三个
double
值?然后您只需要将
Vector3
的内部数组设置为给定数组,就不会进行复制。如果他的结构包含数组,则每个数组都需要堆分配,并且与此紧凑结构相比,数组本身会引入相当多的内存开销。