如何在 C# 中将 ExpandoObject 的动态列表转换为字节
How to convert a list of a dynamic of ExpandoObject to byte in C#
目标
- 将当前动态对象保存到文件
- 加载存档并设置
我搜索并找到了以下方法。但它用于可序列化 field/class.
可序列化
public byte[] ToByteArray<T>(T obj)
{
BinaryFormatter b = new BinaryFormatter()
using(MemoryStream m = new MemoryStream)
{
b.Serialize(m,obj);
return ms.ToArray();
}
}
public T FromByteArray<T>(byte[] data)
{
BinaryFormatter b = new BinaryFormatter()
using(MemoryStream m = new MemoryStream)
{
object obj = b.Deserialize(m);
return (T)obj;
}
}
目标示例
动态 d 不能是可序列化的 class 因为它不仅有 x、y 和 z。我的目标是创建两个功能:将动态列表保存到文件并从文件加载它。
- bool ToFile(List list, string where)
- 列表加载(字符串 其中)
List<dynamic> save = new List<dynamic>();
dynamic d = new ExpandoObject();
d.x = 1;
d.y = 3;
save.add(d);
d.z = 5;
d._type = "1";
save.add(d);
ToFile(save,"C:/Save.byte");
List<dynamic> load = Load("C:/Save.byte");
for(int I = 0; I < load.Count; I++)
{
print("Round " + I);
if(load[I].z != null)
print(load[I].z);
}
控制台
Round 1
Round 2
5
我知道从算法的角度来看这不是您所期望的,但以下解决方案达到了声明的目标。首先,在您的示例中,列表中的两个项目是相同的项目。我将主要代码更改为:
var bs = new BinaryStorage();
List<dynamic> save = new List<dynamic>();
dynamic d = new ExpandoObject();
d.x = 1;
d.y = 3;
d.name = "You can also add text of any length here";
save.Add(d);
dynamic e = new ExpandoObject();
e.z = 5;
e._type = "1";
save.Add(e);
bs.writeToFile(save, "data.bin");
List<dynamic> load = bs.readFromFile("data.bin");
int i = 0;
foreach (var item in load)
{
i++;
Console.WriteLine(item.z == null ? $"{i}: (null)" : $"{i}: {item.z}");
}
BinaryStorage class 看起来像这样:
public class BinaryStorage
{
// add methods CopyTo, Zip, and Unzip
public void writeToFile(List<dynamic> data, string fname)
{
string jtext = JsonConvert.SerializeObject(data, Formatting.None);
File.WriteAllBytes(fname, Zip(jtext));
}
public List<dynamic> readFromFile(string fname)
{
var bin = File.ReadAllBytes(fname);
var res = JsonConvert.DeserializeObject<List<dynamic>>(Unzip(bin));
return res;
}
}
此示例生成 data.bin 99 字节的文件。 class 的其他三种方法你可以从这个答案中得到:
Compression/Decompression string with C#
目标
- 将当前动态对象保存到文件
- 加载存档并设置
我搜索并找到了以下方法。但它用于可序列化 field/class.
可序列化
public byte[] ToByteArray<T>(T obj)
{
BinaryFormatter b = new BinaryFormatter()
using(MemoryStream m = new MemoryStream)
{
b.Serialize(m,obj);
return ms.ToArray();
}
}
public T FromByteArray<T>(byte[] data)
{
BinaryFormatter b = new BinaryFormatter()
using(MemoryStream m = new MemoryStream)
{
object obj = b.Deserialize(m);
return (T)obj;
}
}
目标示例
动态 d 不能是可序列化的 class 因为它不仅有 x、y 和 z。我的目标是创建两个功能:将动态列表保存到文件并从文件加载它。
- bool ToFile(List list, string where)
- 列表加载(字符串 其中)
List<dynamic> save = new List<dynamic>();
dynamic d = new ExpandoObject();
d.x = 1;
d.y = 3;
save.add(d);
d.z = 5;
d._type = "1";
save.add(d);
ToFile(save,"C:/Save.byte");
List<dynamic> load = Load("C:/Save.byte");
for(int I = 0; I < load.Count; I++)
{
print("Round " + I);
if(load[I].z != null)
print(load[I].z);
}
控制台
Round 1
Round 2
5
我知道从算法的角度来看这不是您所期望的,但以下解决方案达到了声明的目标。首先,在您的示例中,列表中的两个项目是相同的项目。我将主要代码更改为:
var bs = new BinaryStorage();
List<dynamic> save = new List<dynamic>();
dynamic d = new ExpandoObject();
d.x = 1;
d.y = 3;
d.name = "You can also add text of any length here";
save.Add(d);
dynamic e = new ExpandoObject();
e.z = 5;
e._type = "1";
save.Add(e);
bs.writeToFile(save, "data.bin");
List<dynamic> load = bs.readFromFile("data.bin");
int i = 0;
foreach (var item in load)
{
i++;
Console.WriteLine(item.z == null ? $"{i}: (null)" : $"{i}: {item.z}");
}
BinaryStorage class 看起来像这样:
public class BinaryStorage
{
// add methods CopyTo, Zip, and Unzip
public void writeToFile(List<dynamic> data, string fname)
{
string jtext = JsonConvert.SerializeObject(data, Formatting.None);
File.WriteAllBytes(fname, Zip(jtext));
}
public List<dynamic> readFromFile(string fname)
{
var bin = File.ReadAllBytes(fname);
var res = JsonConvert.DeserializeObject<List<dynamic>>(Unzip(bin));
return res;
}
}
此示例生成 data.bin 99 字节的文件。 class 的其他三种方法你可以从这个答案中得到:
Compression/Decompression string with C#