ICEATABLEとiSerializableを実装するためのクラスを構成する方法
-
27-09-2019 - |
質問
しばらくの間これに頭を叩いていた
私が抱えている問題は、iLINKなどのセット操作を使用できるように、Iequatableの動作を追加しようとすることです。
現時点で私が持っています...
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」が見つかりませんでした。」これは、それが脱色を試みる最初のメンバーです
ところで:これはリモートであるため、カスタムシリアル化の必要性 - これらの動作を一緒に作成する方法はありますか?
どうもありがとう!
m
解決
サンプルコードはコンパイルされません。 Ilink Interfaceメンバーは実装しません。
次のコードが機能します。
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));
}
}
所属していません StackOverflow