C# 当类具有隐式运算符时,使用BinaryFormatter序列化/反序列化
在服务器和客户端之间传输时,我们使用BinaryFormatter将对象转换为字节 我们需要传输的所有类都使用C# 当类具有隐式运算符时,使用BinaryFormatter序列化/反序列化,c#,implicit-conversion,binaryformatter,C#,Implicit Conversion,Binaryformatter,在服务器和客户端之间传输时,我们使用BinaryFormatter将对象转换为字节 我们需要传输的所有类都使用[Serializable]属性,它正常工作。反序列化时,我们还使用自己的SerializationBinder将其映射到正确的对象类型和程序集 但是,当序列化/反序列化任何具有隐式运算符的对象时,我们会遇到问题。 反序列化时,它会根据运算符类型和值执行此操作,因此可能会丢失信息。 例如,一个具有两个属性和一个隐式运算符的类,它将尝试从隐式运算符类型反序列化对象,而来自这两个属性的值似乎
[Serializable]
属性,它正常工作。反序列化时,我们还使用自己的SerializationBinder将其映射到正确的对象类型和程序集
但是,当序列化/反序列化任何具有隐式运算符的对象时,我们会遇到问题。
反序列化时,它会根据运算符类型和值执行此操作,因此可能会丢失信息。
例如,一个具有两个属性和一个隐式运算符的类,它将尝试从隐式运算符类型反序列化对象,而来自这两个属性的值似乎丢失了
我怎样才能强迫它像其他类一样正常工作?还是我遗漏了什么
更新
在进行进一步研究时,它似乎是一个包装类的组合,该包装类使用返回特定类型的隐式运算符实现ISerializable和child属性
例如:
[Serializable]
class Dto
{
public int MyNumber { get; set; }
// The implicit operator returning an int will be used when deseralized instead of the complete object
// If you change it to the operator returning a string, it will not be used at all.
// Other types like decimal will also trigger the problem, and if multiple are present the int seems to be one that is used.
public static implicit operator int(Dto dto) => dto.MyNumber;
//public static implicit operator string(Dto dto) => dto.MyNumber.ToString();
//public static implicit operator decimal(Dto dto) => (decimal)dto.MyNumber;
}
[Serializable]
class DtoWrapper : ISerializable
{
public Dto Dto { get; set; }
public DtoWrapper() { }
public DtoWrapper(SerializationInfo info, StreamingContext context)
{
Dto = (Dto)info.GetValue(nameof(Dto), typeof(Dto));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(Dto), Dto);
}
}
首先序列化然后反序列化
DtoWrapper
类的实例时,将出现一个错误,即不能从整数设置Dto属性。问题的解决方案是使用AddValue()的重载方法,其中显式设置了类型,如下所示:
info.AddValue(nameof(Dto), Dto, typeof(Dto));
这就解决了问题。要在序列化和反序列化过程中更改类型,需要非常明确的步骤,运算符是不够的。在序列化期间,
SerializationInfo.SetType()
可以更改类型,在反序列化时,IObjectReference
实现可以返回另一个类型,当然自定义绑定器可以通过存储的程序集和类型名映射到任何类型。我打赌是后者,但没有提供一个可复制的例子,我不能确定。我喜欢得到-1,但对不喜欢的东西没有任何评论。@taffer问题不是我想改变类型。它是由BinaryFormatter自动完成的,尽管我不希望这样做。如果我从类中删除隐式运算符方法,一切都会正常工作。这就是为什么我说需要一个。在那之前,我们可以试着说服对方这是否是由于操作员造成的,但这没有意义。在活页夹中,您可以检查存储的类型,以便在需要映射类型时查看反序列化是否正常。