[英]Multi-Dim Array to 1D - getting it to work with protobuf
Protobuf不支持多維度數組,因此我決定使用此實現從2D數組中制作1D數組。 當我調用MultiLoop函數時,在ToProtoArray方法中我Cannot cast from source type to destination type
。 有想法該怎么解決這個嗎?
public static ProtoArray<T> ToProtoArray<T>(this System.Array array)
{
// Copy dimensions (to be used for reconstruction).
var dims = new int[array.Rank];
for (int i = 0; i < array.Rank; i++) dims[i] = array.GetLength(i);
// Copy the underlying data.
var data = new T[array.Length];
var k = 0;
array.MultiLoop(indices => data[k++] = (T)array.GetValue(indices));
// ^^^^^^^^^^ cannot cast from source type to destination type
return new ProtoArray<T> { Dimensions = dims, Data = data };
}
public static System.Array ToArray<T>(this ProtoArray<T> protoArray)
{
// Initialize array dynamically.
var result = System.Array.CreateInstance(typeof(T), protoArray.Dimensions);
// Copy the underlying data.
var k = 0;
result.MultiLoop(indices => result.SetValue(protoArray.Data[k++], indices));
return result;
}
public static void MultiLoop(this System.Array array, System.Action<int[]> action)
{
array.RecursiveLoop(0, new int[array.Rank], action);
}
private static void RecursiveLoop(this System.Array array, int level, int[] indices, System.Action<int[]> action)
{
if (level == array.Rank)
{
action(indices);
}
else
{
for (indices[level] = 0; indices[level] < array.GetLength(level); indices[level]++)
{
RecursiveLoop(array, level + 1, indices, action);
}
}
}
[ProtoContract]
public class ProtoArray<T>
{
[ProtoMember(1)]
public int[] Dimensions { get; set; }
[ProtoMember(2)]
public T[] Data { get; set; }
}
這是我使用它來序列化2D數組的方法:
[ProtoContract]
public class Tile
{
[ProtoMember(1)]
public int x;
[ProtoMember(2)]
public int y;
// ...
}
Tile[,] map; // meanwhile I assign the data to the array
map1d = Extensions.ToProtoArray<Tile[,]>(map);
using (var file = File.Create(path))
{
Serializer.Serialize(file, map1d);
}
我認為這是您需要的:
public class ProtoArray<T>
{
public ProtoArray(T[] array)
{
this.Data=array;
this.Dimensions=new int[array.Length];
}
public ProtoArray(T[,] array)
{
int n = array.GetLength(0);
int m = array.GetLength(1);
this.Data=new T[n*m];
for(int i = 0; i<n; i++)
{
for(int j = 0; j<m; j++)
{
// Row Major
Data[i*m+j]=array[i, j];
// For Column Major use Data[i+j*n]=array[i, j];
}
}
this.Dimensions=new[] { n, m };
}
public int[] Dimensions { get; set; }
public T[] Data { get; set; }
public T[] ToArray()
{
if(Dimensions.Length==1)
{
return Data.Clone() as T[];
}
else
{
throw new NotSupportedException();
}
}
public T[,] ToArray2()
{
if(Dimensions.Length==2)
{
int n = Dimensions[0], m = Dimensions[1];
T[,] array = new T[n, m];
for(int i = 0; i<n; i++)
{
for(int j = 0; j<m; j++)
{
array[i, j]=Data[i*m+j];
}
}
return array;
}
else
{
throw new NotSupportedException();
}
}
}
public class Tile
{
public int x;
public int y;
// ...
}
class Program
{
static void Main(string[] args)
{
Tile[,] map = new Tile[16, 4];
ProtoArray<Tile> array = new ProtoArray<Tile>(map);
//serialize array
//
// de-serialize array
Tile[,] serialized_map = array.ToArray2();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.