2012-04-10 16 views
7

Voglio limitare la creazione dell'oggetto utilizzando il costruttore predefinito. Perché ho un aspetto come di seguito:Progettazione senza costruttore predefinito

class Program 
{ 
    static void Main(string[] args) 
    { 
     BaseClass bc = new BaseClass("",""); 
     XmlSerializer xml = new XmlSerializer(typeof(BaseClass)); 
     StreamWriter sw = new StreamWriter(File.Create("c:\\test.txt")); 
     xml.Serialize(sw,bc); 
     sw.Flush(); 
     sw.Close(); 
    } 
} 
[Serializable] 
public class BaseClass 
{ 
    public string UserName, Password; 
    // I don't want to create default constructor because of Authentication 
    public BaseClass(string _UserName, string _Password) 
    { 
     UserName = _UserName; 
     Password = _Password; 
     f_Authenticate(); 
    } 
    private void f_Authenticate() { } 
} 

public class DerivedClass:BaseClass 
{ 
    public DerivedClass(string _UserName, string _Password) : base(_UserName, _Password) 
    { 
    } 
} 

Questo è ok. Ma quando faccio BaseClass a serializzabile che sarà generare questo errore: Unhandled Exception: System.InvalidOperationException: ConsoleApplication1.BaseC lass cannot be serialized because it does not have a parameterless constructor.

Ora il mio progetto è al collasso, perché ho bisogno di avere Username, Password parametri ma costruttore di default sta rovinando il mio disegno ....

Cosa dovrei?

+0

In realtà voglio imparare tutte le possibilità. se posso/non posso usare cosa mi offri? – uzay95

+0

Duplicato di http://stackoverflow.com/questions/267724/why-xml-serializable-class-need-a-parameterless-constructor – Matten

risposta

12

Creare un costruttore di default privato

private DerivedClass() 
{ 
    // code 
} 

Il serialzer chiamerà con successo questo anche se è privato

+0

No, perché richiede un costruttore predefinito, quindi sarebbe accessibile pubblicamente. –

+1

@TomWijsman Apparentemente no, vedere i commenti sulla risposta di Matten – Robbie

+1

E per essere completamente accurati, è possibile aggiungere [Obsoleto ("Costruttore predefinito è solo per la serializzazione!", True)] a quel costruttore privato, per assicurarsi di non chiamare accidentalmente da dentro la classe. – yoyo

11

La classe deserializzazione istanze richiede un costruttore senza parametri per creare l'istanza, ma non hanno per implementare un costruttore pubblico - è sufficiente avere un costruttore private o internal finché non ha bisogno di parametri.

A proposito, è possibile utilizzare anche lo DataContractSerializer, che non richiede un costruttore senza parametri e crea anche XML; è sempre la mia prima scelta :-)

+1

Utilizza la riflessione – Matten

+0

Non mi ero reso conto che sarebbe stato valido? Mi sarei aspettato che avesse bisogno di un costruttore pubblico. Funziona sicuramente? Se è così, bello! – Liam

+0

@TomWijsmanno, no, intendevo chiamare il costruttore non predefinito (nell'esempio di OP), ma ho rimosso la mia risposta/commento in quanto mi rendo conto che è il serializzatore che chiama il costruttore predefinito e quindi non può essere privato (Immagino) – Robbie

1
  • Hai provato a creare un costruttore privato senza parametri?

  • Se v'è la necessità di una pubblica, si può sempre commento che dice che non dovrebbe essere usato (non è la soluzione migliore)

È necessario anche creare le proprietà della tua classe Serializable. Le variabili non sono considerate e non saranno lette o scritte durante il processo di serializzazione/deserealizzazione

Problemi correlati