.Net XML 序列化器和矩阵
.Net XML Serializer and matrix
我在 C# 项目中封装并使用了 C++/CLI 代码。
我在 C++/CLI 代码中有一个 class,其中包含一个声明如下的矩阵:
array<double, 2>^ S_to_Box_Matrix;
S_to_Box_Matrix = gcnew array<double, 2>(4, 4);
看来这个变量是不可序列化的。
如何使其可序列化?
如果不可能,那么如何将其排除在序列化之外(哪个 C++/CLI 关键字和要导入的库)
谢谢
XmlSerializer
不支持二维数组。解决这个问题最直接的方法是修改你的 c++/cli class 如下:
- 用
[XmlIgnore]
标记二维数组
- 引入代理 属性 将二维数组与锯齿状数组相互转换。
- 用
[XmlArray]
标记锯齿状数组属性
例如:
#using <System.Xml.dll>
public ref class Array2DTestClass
{
public:
[System::Xml::Serialization::XmlIgnore]
array<double, 2> ^S_to_Box_Matrix;
[System::Xml::Serialization::XmlArray("S_to_Box_Matrix")]
property array<array<double> ^>^ S_to_Box_Matrix_Serializable {
array<array<double> ^>^ get();
System::Void set(array<array<double> ^>^ value);
}
};
有实现
array<array<double> ^>^ Array2DTestClass::S_to_Box_Matrix_Serializable::get() {
return ArrayExtensions::ToJaggedArray(this->S_to_Box_Matrix);
}
System::Void Array2DTestClass::S_to_Box_Matrix_Serializable::set(array<array<double> ^>^ value) {
this->S_to_Box_Matrix = ArrayExtensions::To2DArray(value);
}
使用辅助方法:
public ref class ArrayExtensions abstract sealed {
public:
generic<typename T> static array<array<T>^> ^ToJaggedArray(array<T, 2> ^input)
{
if (input == nullptr)
return nullptr;
int nRow = input->GetLength(0);
int nCol = input->GetLength(1);
array<array<T>^> ^output = gcnew array<array<T>^>(nRow);
for (int iRow = 0; iRow < nRow; iRow++)
{
output[iRow] = gcnew array<T>(nCol);
for (int iCol = 0; iCol < nCol; iCol++)
output[iRow][iCol] = input[iRow, iCol];
}
return output;
}
generic<typename T> static array<T, 2> ^To2DArray(array<array<T> ^>^input)
{
if (input == nullptr)
return nullptr;
int nRow = input->Length;
int nCol = 0;
for (int iRow = 0; iRow < nRow; iRow++)
if (input[iRow] != nullptr)
nCol = Math::Max(nCol, input[iRow]->Length);
array<T, 2> ^ output = gcnew array<T, 2>(nRow, nCol);
for (int iRow = 0; iRow < nRow; iRow++)
if (input[iRow] != nullptr)
for (int iCol = 0; iCol < input[iRow]->Length; iCol++)
output[iRow, iCol] = input[iRow][iCol];
return output;
}
};
这样做,我得到 XML 看起来像:
<Array2DTestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<S_to_Box_Matrix>
<ArrayOfDouble>
<double>0</double>
<double>1</double>
<double>2</double>
</ArrayOfDouble>
<ArrayOfDouble>
<double>3</double>
<double>4</double>
<double>5</double>
</ArrayOfDouble>
</S_to_Box_Matrix>
</Array2DTestClass>
我在 C# 项目中封装并使用了 C++/CLI 代码。 我在 C++/CLI 代码中有一个 class,其中包含一个声明如下的矩阵:
array<double, 2>^ S_to_Box_Matrix;
S_to_Box_Matrix = gcnew array<double, 2>(4, 4);
看来这个变量是不可序列化的。 如何使其可序列化? 如果不可能,那么如何将其排除在序列化之外(哪个 C++/CLI 关键字和要导入的库) 谢谢
XmlSerializer
不支持二维数组。解决这个问题最直接的方法是修改你的 c++/cli class 如下:
- 用
[XmlIgnore]
标记二维数组
- 引入代理 属性 将二维数组与锯齿状数组相互转换。
- 用
[XmlArray]
标记锯齿状数组属性
例如:
#using <System.Xml.dll>
public ref class Array2DTestClass
{
public:
[System::Xml::Serialization::XmlIgnore]
array<double, 2> ^S_to_Box_Matrix;
[System::Xml::Serialization::XmlArray("S_to_Box_Matrix")]
property array<array<double> ^>^ S_to_Box_Matrix_Serializable {
array<array<double> ^>^ get();
System::Void set(array<array<double> ^>^ value);
}
};
有实现
array<array<double> ^>^ Array2DTestClass::S_to_Box_Matrix_Serializable::get() {
return ArrayExtensions::ToJaggedArray(this->S_to_Box_Matrix);
}
System::Void Array2DTestClass::S_to_Box_Matrix_Serializable::set(array<array<double> ^>^ value) {
this->S_to_Box_Matrix = ArrayExtensions::To2DArray(value);
}
使用辅助方法:
public ref class ArrayExtensions abstract sealed {
public:
generic<typename T> static array<array<T>^> ^ToJaggedArray(array<T, 2> ^input)
{
if (input == nullptr)
return nullptr;
int nRow = input->GetLength(0);
int nCol = input->GetLength(1);
array<array<T>^> ^output = gcnew array<array<T>^>(nRow);
for (int iRow = 0; iRow < nRow; iRow++)
{
output[iRow] = gcnew array<T>(nCol);
for (int iCol = 0; iCol < nCol; iCol++)
output[iRow][iCol] = input[iRow, iCol];
}
return output;
}
generic<typename T> static array<T, 2> ^To2DArray(array<array<T> ^>^input)
{
if (input == nullptr)
return nullptr;
int nRow = input->Length;
int nCol = 0;
for (int iRow = 0; iRow < nRow; iRow++)
if (input[iRow] != nullptr)
nCol = Math::Max(nCol, input[iRow]->Length);
array<T, 2> ^ output = gcnew array<T, 2>(nRow, nCol);
for (int iRow = 0; iRow < nRow; iRow++)
if (input[iRow] != nullptr)
for (int iCol = 0; iCol < input[iRow]->Length; iCol++)
output[iRow, iCol] = input[iRow][iCol];
return output;
}
};
这样做,我得到 XML 看起来像:
<Array2DTestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <S_to_Box_Matrix> <ArrayOfDouble> <double>0</double> <double>1</double> <double>2</double> </ArrayOfDouble> <ArrayOfDouble> <double>3</double> <double>4</double> <double>5</double> </ArrayOfDouble> </S_to_Box_Matrix> </Array2DTestClass>