Gaz*_*yer 5 c# wcf serialization immutability datacontractserializer
我有一个实际上是基于对象的枚举的类.该类公开了一组静态对象,并且所有对象都使用这些相同的实例.例如(注意私有构造函数)
[DataContract]
public class FieldType
{
public static readonly FieldType Default = new FieldType(1, "Default");
public static readonly FieldType Name = new FieldType(2, "Name");
public static readonly FieldType Etc = new FieldType(3, "Etc");
private FieldType(uint id, string name)
{
Id = id;
Name = name;
}
[DataMember] public uint Id { get; private set; }
[DataMember] public string Name { get; private set; }
//snip other properties
}
Run Code Online (Sandbox Code Playgroud)
这非常有效,直到我必须在WCF中进行序列化.在DataContractSerializer创建绕过构造新的对象.这会产生一个有效的FieldType对象,但它是一个不是我的静态实例之一的新实例.这使得与已知静态值的参考比较失败.
有没有办法覆盖类的序列化行为,以便我创建对象实例而不是填充提供给我的实例?
我怀疑你能做到:
[DataContract]
public class FieldType : IObjectReference
{
object IObjectReference.GetRealObject(StreamingContext ctx)
switch(Id) {
case 1: return Default;
case 2: return Name; // note this is a collision between static/non-static
case 3: return Etc;
default: throw new InvalidOperationException();
}
}
public static readonly FieldType Default = new FieldType(1, "Default");
// note this is a collision between static/non-static
public static readonly FieldType Name = new FieldType(2, "Name");
public static readonly FieldType Etc = new FieldType(3, "Etc");
private FieldType(uint id, string name)
{
Id = id;
Name = name; // note this is a collision between static/non-static
}
[DataMember] public uint Id { get; private set; }
// note this is a collision between static/non-static
[DataMember] public string Name { get; private set; }
//snip other properties
}
Run Code Online (Sandbox Code Playgroud)
验证:
public static class Program
{
static void Main()
{
var obj = FieldType.Default;
using(var ms = new MemoryStream())
{
var ser = new DataContractSerializer(typeof (FieldType));
ser.WriteObject(ms, obj);
ms.Position = 0;
var obj2 = ser.ReadObject(ms);
bool pass = ReferenceEquals(obj, obj2); // true
}
}
}
Run Code Online (Sandbox Code Playgroud)
但请注意,Name如果我们仅使用它Id来识别要使用的真实对象,那么序列化似乎没什么意义.
我建议您覆盖Equalsand GetHashcode(和==and !=),以便您对静态对象与 WCF 创建的对象进行相等性检查。
数据传输对象 (DTO) 不适用于面向对象的行为,它们纯粹是状态类。但我能理解你面临的问题。
或者,当域对象与上述类一起工作时,使用不同的 DTO 来发送数据。