0

しばらくの間、これについて頭を悩ませてきました

私が抱えている問題は、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 "Member 'Linkid' was not found." が発生します。これは、逆シリアル化を試みる最初のメンバーです

ところで:これはリモーティングであるため、カスタムのシリアル化が必要です-これらの動作を一緒に構成する方法はありますか?

どうもありがとう!

M

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 に答える