2010-08-10 21 views
0

被敲我的頭這一段時間現在如何構建類來實現IEquatable和ISerializable的

我正試圖添加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'」。這是它試圖反序列化的第一個成員

順便說一句:這是遠程處理,因此需要自定義序列化 - 是否有辦法一起組合這些行爲?

非常感謝!

M

回答

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)); 
    } 
} 
+0

上面的代碼只是爲了說明而不是編譯,但是您已經將我設置在正確的路徑上。非常感謝! – MikeW 2010-08-11 01:48:05

相關問題