我有一个实际上是基于对象的枚举的类。该类公开了一组静态对象,并且所有对象都使用这些相同的实例。例如(注意私有构造函数)
[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
}
这非常有效,直到我必须在WCF中进行序列化。 DataContractSerializer
绕过构造函数创建新对象。这会生成一个有效的FieldType
对象,但它是一个不是我的静态实例之一的新实例。这使得与已知静态值的参考比较失败。
有没有办法覆盖类的序列化行为,以便创建对象实例而不是填充提供给我的实例?
答案 0 :(得分:8)
我怀疑你可以这样做:
[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
}
验证
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
}
}
}
但请注意,如果我们仅使用Name
来标识要使用的真实对象,那么序列化Id
似乎没什么意义。
答案 1 :(得分:4)
我建议您覆盖Equals
和GetHashcode
(以及==
和!=
),以便使用WCF创建的静态对象进行等效检查。
数据传输对象(DTO)不适用于面向对象的行为,它们只是纯粹的状态类。但我能理解你所面临的问题。
或者,当您的域对象使用上述类时,使用不同的DTO发送数据。