0

一段时间以来一直在努力解决这个问题

我遇到的问题是尝试添加 IEquatable 行为,以便我的派生类可以使用 ILink 等的集合操作相交。

此刻我有...

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'。” 这是它尝试反序列化的第一个成员

顺便说一句:这是远程处理,因此需要自定义序列化 - 有没有办法将这些行为组合在一起?

非常感谢!

4

1 回答 1

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));
    }
}
于 2010-08-10T07:37:14.953 回答