2012-04-10 3 views
7

Je souhaite limiter la création d'objet en utilisant le constructeur par défaut. Parce que j'ai un desing comme ci-dessous:Conception sans constructeur par défaut

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) 
    { 
    } 
} 

Ceci est ok. Mais quand je fais BaseClass à SERIALIZABLE il va générer cette erreur: Unhandled Exception: System.InvalidOperationException: ConsoleApplication1.BaseC lass cannot be serialized because it does not have a parameterless constructor.

Maintenant, ma conception croule parce que je dois avoir Username, mais Password paramètres constructeur par défaut est ruiner ma conception ....

Qu'est-ce que devrais-je?

+0

En fait, je veux apprendre toutes les possibilités. Si je peux/ne peux pas utiliser ce que tu m'offres? – uzay95

+0

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

Répondre

12

Créer un constructeur par défaut privé

private DerivedClass() 
{ 
    // code 
} 

Le serialzer appellera avec succès ce même si elle est privée

+0

Non, car il nécessite un constructeur par défaut, donc il serait accessible publiquement. –

+1

@TomWijsman Apparemment pas, voir les commentaires sur la réponse de Matten – Robbie

+1

Et pour être complètement complet, vous pouvez ajouter [Obsolète ("constructeur par défaut est seulement pour la sérialisation!", True)] à ce constructeur privé, pour vous assurer de ne pas appeler accidentellement de l'intérieur de la classe. – yoyo

11

La classe désérialisation vos instances nécessite un constructeur sans paramètre pour créer l'instance, mais vous n'avez pas pour implémenter un constructeur public - il suffit d'avoir un constructeur private ou internal tant qu'il n'a pas besoin de paramètres. Par ailleurs, vous pouvez aussi utiliser le DataContractSerializer, qui ne nécessite pas de constructeur sans paramètre et qui crée aussi du XML; c'est toujours mon premier choix :-)

+1

Il utilise la réflexion – Matten

+0

Je ne savais pas que ce serait valide? Je m'attendais à avoir besoin d'un constructeur public. Est-ce que cela fonctionne vraiment? Si c'est le cas, cool! – Liam

+0

@TomWijsmanno, non, je voulais dire en appelant le constructeur par défaut (dans l'exemple de OP), mais j'ai supprimé ma réponse/commentaire car je me rends compte que c'est le sérialiseur qui appelle le constructeur par défaut et donc il ne peut pas être privé (Je suppose) – Robbie

1
  • Avez-vous essayé de créer un constructeur privé sans paramètre?

  • S'il y a le besoin d'un public, vous pouvez toujours du commentaire dire qu'il ne doit pas être utilisé (pas la meilleure solution)

Vous devez également créer des propriétés dans votre classe Serializable. Les variables ne sont pas prises en compte et ne seront pas lues ou écrites pendant le processus de sérialisation/désertification

Questions connexes