2009-05-04 13 views
8

Ho 2 interfacce IA e IB.Come posso serializzare un oggetto che ha un'interfaccia come una proprietà?

public interface IA 
{ 
    IB InterfaceB { get; set; } 
} 

public interface IB 
{ 
    IA InterfaceA { get; set; } 

    void SetIA(IA value); 
} 

Ogni interfaccia fa riferimento all'altra.

Sto cercando di serializzare ClasseA come definito di seguito.

[Serializable] 
public class ClassA : IA 
{ 
    public IB InterfaceB { get; set; } 

    public ClassA() 
    { 
     // Call outside function to get Interface B 
     IB interfaceB = Program.GetInsanceForIB(); 

     // Set IB to have A 
     interfaceB.SetIA(this); 
    } 
} 

[Serializable] 
public class ClassB : IB 
{ 
    public IA InterfaceA { get; set; } 

    public void SetIA(IA value) 
    { 
     this.InterfaceA = value as ClassA; 
    } 
} 

Viene visualizzato un errore quando si tenta di serializzare troppo perché le 2 proprietà sono interfacce. Voglio serializzare le proprietà.

Come potrei aggirare questo?

ho bisogno di avere riferimenti in ogni interfaccia verso l'altro. E ho bisogno di essere in grado di serializzare la classe avanti e indietro.

risposta

10

Sono disponibili varie bug nel codice, altrimenti questo avrebbe funzionato bene.

  1. Nel costruttore per ClassA, si imposta una variabile locale IB, non l'oggetto IB dell'oggetto.
  2. In ClassB, si sta casting torna alla classe oggetto concreto, invece di lasciarlo da solo come il tipo di interfaccia.

Ecco quello che il codice dovrebbe essere simile:

public interface IA 
{ 
    IB InterfaceB { get; set; } 
} 

public interface IB 
{ 
    IA InterfaceA { get; set; } 
    void SetIA(IA value); 
} 

[Serializable] 
public class ClassA : IA 
{  
    public IB InterfaceB { get; set; }  

    public ClassA()  
    {   
     // Call outside function to get Interface B   
     this.InterfaceB = new ClassB(); 

     // Set IB to have A   
     InterfaceB.SetIA(this);  
    } 
} 

[Serializable] 
public class ClassB : IB 
{  
    public IA InterfaceA { get; set; }  

    public void SetIA(IA value)  
    {  
     this.InterfaceA = value;  
    } 
} 

[STAThread] 
static void Main() 
{ 
    MemoryStream ms = new MemoryStream(); 
    BinaryFormatter bin = new BinaryFormatter(); 

    ClassA myA = new ClassA(); 

    bin.Serialize(ms, myA); 

    ms.Position = 0; 

    ClassA myOtherA = bin.Deserialize(ms) as ClassA; 


    Console.ReadLine(); 
} 
+0

Ho risolto i bug ed è stato possibile andare avanti e indietro. –

+0

Sì. È facile arrivare agli errori di copia-incolla. Sono contento che questo sia stato di aiuto. –

0

Supponendo che non si vuole serializzare la proprietà di interfaccia, inserire il seguente attributo

[NonSerialized] 

sulla proprietà di interfaccia.

+1

Voglio serializzare le proprietà. Ho riformulato la domanda per riflettere questo. –

+0

È possibile farlo con un serializzatore/deserializzatore personalizzato. Nel serializzatore personalizzato manterrai semplicemente le informazioni aggiuntive sull'oggetto che è contenuto nella proprietà dell'interfaccia. Si potrebbe anche evitare il riferimento circolare che non ci sarebbe dubbio mantenendo un semplice conteggio di ciò che si è già serializzato/deserializzato. – rein

0

In cambio della tua domanda: altre due domande. Cosa serializzi? Il database è di riferimento?

Non serializzare interfacce; serializzi gli oggetti. L'oggetto che serializzi è un'implementazione di IA o IB.

Sta a l'oggetto serializzato per decidere se una delle sue proprietà deve essere serializzato o meno. Se la proprietà ha bisogno di serializzazione, è necessario implementare l'interfaccia Serializable con.

È possibile serializzare solo una cosiddetta "isola" formata da un riferimento circolare A < -> B se il database è in grado di identificare gli oggetti serializzati: deve innanzitutto "allocare" lo spazio per A, avviare la serializzazione delle proprietà di A. Quando arriva a B, troverà una delle sue proprietà che si riferiscono ad A. La serializzazione dovrebbe quindi includere un riferimento alla versione serializzata di A.

È molto simile a due conoscenti che spostano case contemporaneamente: prima saranno scambiare i loro futuri indirizzi, solo allora si muoveranno fisicamente.

2

Implementare ISerializable sui vostri oggetti per controllare la serializzazione.

[Serializable] 
public class ClassB : IB, ISerializable 
{ 
    public IA InterfaceA { get; set; } 

    public void SetIA(IA value) 
    { 
    this.InterfaceA = value as ClassA; 
    } 

    private MyStringData(SerializationInfo si, StreamingContext ctx) { 
    Type interfaceAType = System.Type.GetType(si.GetString("InterfaceAType")); 
    this.InterfaceA = si.GetValue("InterfaceA", interfaceAType); 
    } 

    void GetObjectData(SerializationInfo info, StreamingContext ctx) { 
    info.AddValue("InterfaceAType", this.InterfaceA.GetType().FullName); 
    info.AddValue("InterfaceA", this.InterfaceA); 
    } 
} 
+0

Le modifiche alla classe A vengono lasciate come esercizio al lettore. :) È praticamente la stessa cosa. – Greg

-1

Le proprietà dell'interfaccia non sono serializzabili. Tuttavia, i campi che fanno riferimento a tali proprietà (nella sottoclasse) lo sono.

Avrai bisogno di fare qualcosa di simile:

[Serializable] 
public class ClassA : IA 
{ 
    private IB _interfaceB; 
    public IB InterfaceB { get { return _interfaceB; } set { _interfaceB = value; } } 

    public ClassA() 
    { 
     // Call outside function to get Interface B 
     IB interfaceB = Program.GetInsanceForIB(); 

     // Set IB to have A 
     interfaceB.SetIA(this); 
    } 
} 

[Serializable] 
public class ClassB : IB 
{ 
    private IA _interfaceA; 
    public IA InterfaceA { get { return _interfaceA; } set { _interfaceA = value; } } 

    public void SetIA(IA value) 
    { 
     this.InterfaceA = value as ClassA; 
    } 
} 
+0

Non ho avuto problemi a serializzare il grafico dell'oggetto. Dove ottieni che le proprietà dell'interfaccia non siano serializzabili? Inoltre, perché avere l'istanza privata quando la proprietà automatica funziona bene? –

+0

Oops. Ciò era dovuto a un fondamentale fraintendimento (da parte mia) di ciò che è e non è serializzabile. (Ho sempre sbagliato tutto). Le interfacce NON sono serializzabili; le proprietà in una classe derivata da un'interfaccia SONO serializzabili. Grazie per la segnalazione. –

Problemi correlati