现在已经暂时搁置了一段时间
我遇到的问题是尝试添加IEquatable行为,因此我的派生类可以使用ILink等的集合操作Intersect。
此刻我......
public interface ILink
{
int Linkid { get; set; }
bool IsActive { get; set; }
}
和一堆派生类,如
public class Domain : ILink
{
public Domain(){}
}
public class User : ILink
{
public User (){}
}
所以为了做列表的交集 我以为我会像这样创建一个抽象类......
public abstract class AbstractLink : IEquatable<ILink>, ISerializable, ILink
{
public AbstractLink(){}
public AbstractLink(SerializationInfo info, StreamingContext ctxt)
{}
public virtual void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{}
}
然而,当我从
更改派生类型时 public class DomainLink : ILink
{
}
到
public class DomainLink : AbstractLink
{
}
我收到一个SerializationException“找不到会员'Linkid'。”这是它尝试反序列化的第一个成员
BTW:这是Remoting因此需要自定义序列化 - 有没有办法将这些行为组合在一起?非常感谢!
中号
答案 0 :(得分:1)
您的示例代码无法编译。您没有实现ILink接口成员。
以下代码确实有效。
覆盖AbstractLink的每个对象都需要一个序列化构造函数。 AbstractLink的每个子类也需要使用[Serializable]进行注释。如果向域对象添加额外属性,则还需要为额外属性实现GetObjectData()。
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public interface ILink
{
int Linkid { get; set; }
bool IsActive { get; set; }
}
[Serializable]
public class Domain : AbstractLink
{
public Domain()
{
}
public Domain(SerializationInfo info, StreamingContext ctx)
: base(info, ctx)
{
}
}
[Serializable]
public class User : AbstractLink
{
public string UserName { get; set; }
public User()
{
}
public User(SerializationInfo info, StreamingContext ctx)
: base(info, ctx)
{
UserName = info.GetString("UserName");
}
public override void GetObjectData(SerializationInfo info, StreamingContext ctx)
{
base.GetObjectData(info, ctx);
info.AddValue("UserName", UserName);
}
}
public abstract class AbstractLink : ISerializable, ILink, IEquatable<ILink>
{
public AbstractLink() { }
public AbstractLink(SerializationInfo info, StreamingContext ctx)
{
Linkid = info.GetInt32("Linkid");
IsActive = info.GetBoolean("IsActive");
}
public virtual void GetObjectData(SerializationInfo info, StreamingContext ctx)
{
info.AddValue("Linkid", Linkid);
info.AddValue("IsActive", IsActive);
}
public bool Equals(ILink other)
{
if (ReferenceEquals(null, other))
return false;
if (ReferenceEquals(this, other))
return true;
return other.Linkid == Linkid && other.IsActive.Equals(IsActive);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
return obj.GetType() == typeof(AbstractLink) && Equals((AbstractLink) obj);
}
public override int GetHashCode()
{
unchecked
{
return (Linkid * 397) ^ IsActive.GetHashCode();
}
}
public int Linkid { get; set; }
public bool IsActive { get; set; }
}
class Program
{
static void Main(string[] args)
{
var user = new User { UserName = "user", IsActive = true, Linkid = 1 };
User user2;
using (var ms = new MemoryStream())
{
var bf = new BinaryFormatter();
bf.Serialize(ms, user);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
user2 = bf.Deserialize(ms) as User;
}
Debug.Assert(user2 != null);
Debug.Assert(ReferenceEquals(user, user2) == false);
Debug.Assert(Equals(user.Linkid, user2.Linkid));
Debug.Assert(Equals(user.IsActive, user2.IsActive));
Debug.Assert(Equals(user.UserName, user2.UserName));
}
}