如果我在运行。net Core的应用程序中序列化我的类,然后将其加载到运行在完整。net框架上的应用程序中,那么任何类型为Type
的变量都将被反序列化为null。
public class protobufTest
{
string framework;
public protobufTest()
{
string writeToFile1 = @"C:temptestClassNetFramework.pbf", writeToFile2 = @"C:temptestClassNET.pbf";
framework = Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
Console.WriteLine("Current framework is " + framework);
string writeToFile;
if (framework.Contains(".NETFramework", StringComparison.OrdinalIgnoreCase)) writeToFile = writeToFile1;
else if (framework.Contains(".NETCoreApp", StringComparison.OrdinalIgnoreCase)) writeToFile = writeToFile2;
else throw new Exception("haven't allowed for framework " + framework);
var tc = make();
write(tc, writeToFile);
Console.WriteLine($"nnwritten to: {writeToFile}n{tc.ToString()}");
if (File.Exists(writeToFile1))
{
var tc1 = Load(writeToFile1);
Console.WriteLine($"nnread from: {writeToFile1}n{tc1.ToString()}");
}
if (File.Exists(writeToFile2))
{
var tc2 = Load(writeToFile2);
Console.WriteLine($"nnread from: {writeToFile2}n{tc2.ToString()}");
}
}
testClass make()
{
var tc = new testClass();
tc.frameworkWhenSaved = framework;
tc.aType = typeof(long);
tc.types.Add(typeof(int));
tc.types.Add(typeof(char));
return tc;
}
testClass Load(string fullFileName)
{
MemoryStream ms;
using (FileStream file = new FileStream(fullFileName, FileMode.Open, FileAccess.Read))
{
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms = new MemoryStream(bytes);
}
ms.Position = 0;
testClass tc = Serializer.Deserialize<testClass>(ms);
return tc;
}
void write(testClass tc, string fullFileName)
{
MemoryStream ms = new MemoryStream();
Serializer.Serialize<testClass>(ms, tc);
ms.Position = 0;
using (FileStream file = new FileStream(fullFileName, FileMode.Create, System.IO.FileAccess.Write))
{
byte[] bytes = new byte[ms.Length];
ms.Read(bytes, 0, (int)ms.Length);
file.Write(bytes, 0, bytes.Length);
ms.Close();
}
}
}
当我在。net Core中运行时,我得到了预期的输出:
Current framework is .NETCoreApp,Version=v7.0
written to: C:temptestClassNET.pbf testClass created by .NETCoreApp,Version=v7.0 aType=System.Int64 types=System.Int32,System.Char,
read from: C:temptestClassNetFramework.pbf testClass created by .NETFramework,Version=v4.7.2 aType=System.Int64 types=System.Int32,System.Char,
read from: C:temptestClassNET.pbf testClass created by .NETCoreApp,Version=v7.0 aType=System.Int64 types=System.Int32,System.Char,
但是当我在完整的。net框架上运行它时,Types
被反序列化为null -仅来自。net Core保存的文件.
Current framework is .NETFramework,Version=v4.7.2
written to: C:temptestClassNetFramework.pbf testClass created by .NETFramework,Version=v4.7.2 aType=System.Int64 types=System.Int32,System.Char,
read from: C:temptestClassNetFramework.pbf testClass created by .NETFramework,Version=v4.7.2 aType=System.Int64
types=System.Int32,System.Char,
read from: C:temptestClassNET.pbf testClass created by .NETCoreApp,Version=v7.0 aType= types=null,null,
(你需要在每个框架中运行一次来生成文件)。
为什么Types
不能正确反序列化?
Type
类实际上是一个被设计为可继承的基类,并且您并不真正创建它的实例,因此没有理由序列化它。(我确信序列化抽象类是有原因的,但Type
更像是一个静态定义)。请看这个SO答案,这里和这里。
不确定你的testClass
是如何定义的,但如果它看起来像这样,那么就序列化到string
:
testClass make()
{
var tc = new testClass();
tc.frameworkWhenSaved = framework;
tc.aType = typeof(long).FullName;
tc.types.Add(typeof(int).FullName);
tc.types.Add(typeof(char).FullName);
return tc;
}
[ProtoContract]
public class testClass
{
public testClass()
{
types = new List<string>();
}
[ProtoMember(1)]
public string frameworkWhenSaved { get; set; }
[ProtoMember(2)]
public string aType { get; set; }
[ProtoMember(3)]
public List<string> types { get; set; }
}
和protobuf-net
可以正确地反序列化到这个类:
[ProtoContract]
public class testClass
{
public testClass()
{
types = new List<Type>();
}
[ProtoMember(1)]
public string frameworkWhenSaved { get; set; }
[ProtoMember(2)]
public Type aType { get; set; }
[ProtoMember(3)]
public List<Type> types { get; set; }
}