2012-04-10 19 views
7

Quiero restringir la creación de objetos usando el constructor predeterminado. Porque tengo un diseño como a continuación:Diseño sin el constructor predeterminado

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

Esto está bien. Pero cuando hago BaseClass a SERIALIZABLE que va a generar este error: Unhandled Exception: System.InvalidOperationException: ConsoleApplication1.BaseC lass cannot be serialized because it does not have a parameterless constructor.

Ahora mi diseño está colapsando porque necesitan tener Username, pero Password parámetros constructor por defecto está arruinando mi diseño ....

Lo ¿deberia hacer?

+0

En realidad, quiero aprender todas las posibilidades. si puedo/no puedo usar ¿qué me ofrecerías? – uzay95

+0

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

Respuesta

12

Crear un constructor por defecto privada

private DerivedClass() 
{ 
    // code 
} 

El serialzer llamará con éxito este a pesar de que es privado

+0

No, porque requiere un constructor predeterminado, por lo que se accederá públicamente. –

+1

@TomWijsman Aparentemente no, vea comentarios en la respuesta de Matten – Robbie

+1

Y para ser completamente minucioso, puede agregar [Obsoleto ("¡Constructor por defecto es solo para serialización!", Verdadero)] a ese constructor privado, para asegurarse de que no llame accidentalmente desde dentro de la clase. – yoyo

11

La clase deserializar instancias requiere un constructor sin parámetros para crear la instancia, pero que no tienen para implementar un constructor público: es suficiente tener un constructor private o internal, siempre que no necesite parámetros.

Por cierto, también puede usar el DataContractSerializer, que no requiere un constructor sin parámetros y también crea XML; siempre es mi elección principal :-)

+1

Utiliza la reflexión – Matten

+0

¿No me di cuenta de que esto sería válido? Esperaba que necesitara un constructor público. ¿Esto definitivamente funciona? Si es así, genial! – Liam

+0

@TomWijsmanno, no, me refiero a llamar al constructor no predeterminado (en el ejemplo de OP), pero he eliminado mi respuesta/comentario ya que me doy cuenta de que es el serializador el que llama al constructor predeterminado y por lo tanto no puede ser privado (supongo) – Robbie

1
  • ¿Has intentado crear un constructor privado sin parámetros?

  • Si existe la necesidad de una pública, siempre se puede comentario diciendo que no se debe utilizar (no la mejor solución)

También es necesario crear propiedades de su clase Serializable. Las variables no se consideran y no se leerán o escribirán durante el proceso de serialización/deserealización

Cuestiones relacionadas