Вы можете использовать новые Span<T>
и MemoryMarshal
типы для этого.
Обратите внимание, что это доступно только в последних версиях C #, и вы должны использоватьПакет NuGet для предоставления библиотеки в данный момент, но это изменится.
Так, например, чтобы «привести» массив char к короткому массиву, вы можете написать код, подобный этому:
var charArray = new char[100];
Span<short> shortArray = MemoryMarshal.Cast<char, short>(charArray);
charArray[0] = 'X';
Console.WriteLine(charArray[0]); // Prints 'X'
++shortArray[0];
Console.WriteLine(charArray[0]); // Prints 'Y'
Этот подход задокументирован и не создает никаких копий каких-либо данных - и он также чрезвычайно эффективен (по замыслу).
Обратите внимание, что это также работает со структурами:
struct Test
{
public int X;
public int Y;
public override string ToString()
{
return $"X={X}, Y={Y}";
}
}
...
var testArray = new Test[100];
Span<long> longArray = MemoryMarshal.Cast<Test, long>(testArray);
testArray[0].X = 1;
testArray[0].Y = 2;
Console.WriteLine(testArray[0]); // Prints X=1, Y=2
longArray[0] = 0x0000000300000004;
Console.WriteLine(testArray[0]); // Prints X=4, Y=3
Такжеобратите внимание, что это позволяет вам делать некоторые подозрительные вещи, например:
struct Test1
{
public int X;
public int Y;
public override string ToString()
{
return $"X={X}, Y={Y}";
}
}
struct Test2
{
public int X;
public int Y;
public int Z;
public override string ToString()
{
return $"X={X}, Y={Y}, Z={Z}";
}
}
...
var test1 = new Test1[100];
Span<Test2> test2 = MemoryMarshal.Cast<Test1, Test2>(test1);
test1[1].X = 1;
test1[1].Y = 2;
Console.WriteLine(test1[1]); // Prints X=1, Y=2
test2[0].Z = 10; // Actually sets test1[1].X.
Console.WriteLine(test1[1]); // Prints X=10, Y=2