why what una sharp que parcial metodo ejemplo classes clase c# web-services wsdl override partial-classes

una - what is a class in c#



Anular constructor predeterminado de clase parcial con otra clase parcial (11)

A veces no tienes acceso o no puedes cambiar el constructor predeterminado, por esta razón no puedes tener el constructor predeterminado para llamar a ningún método.

En este caso, puede crear otro constructor con un parámetro ficticio y hacer que este nuevo constructor llame al constructor predeterminado usando ": this ()"

public SomeClass(int x) : this() { //Your extra initialization here }

Y cuando creas una nueva instancia de esta clase, pasas un parámetro ficticio como este:

SomeClass objSomeClass = new SomeClass(0);

No creo que esto sea posible, pero si es así, lo necesito :)

Tengo un archivo proxy autogenerado de la herramienta de línea de comandos wsdl.exe de Visual Studio 2008.

La salida del proxy es de clases parciales. Quiero sobrescribir el constructor predeterminado que se genera. Preferiría no modificar el código ya que se genera automáticamente.

Intenté hacer otra clase parcial y redefinir el constructor predeterminado, pero eso no funciona. Luego intenté usar la anulación y las nuevas palabras clave, pero eso no funciona.

Sé que podría heredar de la clase parcial, pero eso significaría que tendría que cambiar todo nuestro código fuente para apuntar a la nueva clase principal. Preferiría no tener que hacer esto.

¿Alguna idea, solución de problemas o pirateo?

//Auto-generated class namespace MyNamespace { public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol { public MyWebService() { string myString = "auto-generated constructor"; //other code... } } } //Manually created class in order to override the default constructor namespace MyNamespace { public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol { public override MyWebService() { //this doesn''t work string myString = "overridden constructor"; //other code... } } }


El problema que tiene el OP es que el proxy de referencia web no genera ningún método parcial que pueda usar para interceptar el constructor.

Me encontré con el mismo problema, y ​​no puedo simplemente actualizar a WCF porque el servicio web al que estoy apuntando no lo admite.

No quería modificar manualmente el código autogenerado porque se aplanará si alguien invoca la generación del código.

Abordé el problema desde un ángulo diferente. Sabía que mi inicialización era necesaria antes de una solicitud, realmente no era necesario hacerlo en el momento de la construcción, así que simplemente eliminé el método GetWebRequest.

protected override WebRequest GetWebRequest(Uri uri) { //only perform the initialization once if (!hasBeenInitialized) { Initialize(); } return base.GetWebRequest(uri); } bool hasBeenInitialized = false; private void Initialize() { //do your initialization here... hasBeenInitialized = true; }

Esta es una buena solución, ya que no implica el pirateo del código generado automáticamente, y se ajusta al caso de uso exacto del OP de realizar inicio de sesión de inicialización para un proxy generado automáticamente por SoapHttpClientProtocol.


En realidad, esto ahora es posible, ahora que se han agregado métodos parciales. Aquí está el documento:

http://msdn.microsoft.com/en-us/library/wa80x488.aspx

Básicamente, la idea es que puede declarar y llamar a un método en un archivo donde está definiendo la clase parcial, pero no definir realmente el método en ese archivo. En el otro archivo, puede definir el método. Si está construyendo un ensamblaje donde el método no está definido, entonces el ORM eliminará todas las llamadas a la función.

Entonces, en el caso anterior, se vería así:

// Clase generada automáticamente

namespace MyNamespace { public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol { public MyWebService() { string myString = "auto-generated constructor"; OtherCode(); } } } partial void OtherCode();

// clase creada manualmente para anular el constructor predeterminado

partial void OtherCode() { //do whatever extra stuff you wanted. }

Es algo limitado, y en este caso particular, donde tiene un archivo generado que tendría que modificar, puede que no sea la solución correcta, pero para otros que tropezaron con esto tratando de anular la funcionalidad en clases parciales, esto puede ser bastante útil.


Esto es en mi opinión un defecto de diseño en el lenguaje. Deberían haber permitido implementaciones múltiples de un método parcial, que habría proporcionado una buena solución. De una manera aún más agradable, el constructor (también un método) también puede marcarse simplemente como parcial y múltiples constructores con la misma firma se ejecutarían al crear un objeto.

La solución más simple es, probablemente, agregar un método parcial de ''constructor'' por clase parcial adicional:

public partial class MyClass{ public MyClass(){ ... normal construction goes here ... OnCreated1(); OnCreated2(); ... } public partial void OnCreated1(); public partial void OnCreated2(); }

Si quieres que las clases parciales sean agnósticas entre sí, puedes usar la reflexión:

// In MyClassMyAspect1.cs public partial class MyClass{ public void MyClass_MyAspect2(){ ... normal construction goes here ... } } // In MyClassMyAspect2.cs public partial class MyClass{ public void MyClass_MyAspect1(){ ... normal construction goes here ... } } // In MyClassConstructor.cs public partial class MyClass : IDisposable { public MyClass(){ GetType().GetMethods().Where(x => x.Name.StartsWith("MyClass")) .ForEach(x => x.Invoke(null)); } public void Dispose() { GetType().GetMethods().Where(x => x.Name.StartsWith("DisposeMyClass")) .ForEach(x => x.Invoke(null)); } }

Pero realmente deberían agregar algunas construcciones de lenguaje más para trabajar con clases parciales.


Esto no es posible. Las clases parciales son esencialmente partes de la misma clase; ningún método puede definirse dos veces o anularse, y eso incluye el constructor.

Puede llamar a un método en el constructor y solo implementarlo en el otro archivo de parte.



Hmmm, creo que una solución elegante sería la siguiente:

//* AutogenCls.cs file //* Let say the file is auto-generated ==> it will be overridden each time when //* auto-generation will be triggered. //* //* Auto-generated class, let say via xsd.exe //* partial class AutogenCls { public AutogenCls(...) { } } //* AutogenCls_Cunstomization.cs file //* The file keeps customization code completely separated from //* auto-generated AutogenCls.cs file. //* partial class AutogenCls { //* The following line ensures execution at the construction time MyCustomization m_MyCustomizationInstance = new MyCustomization (); //* The following inner&private implementation class implements customization. class MyCustomization { MyCustomization () { //* IMPLEMENT HERE WHATEVER YOU WANT TO EXECUTE DURING CONSTRUCTION TIME } } }

Este enfoque tiene algunos inconvenientes (como todo):

  1. No está claro exactamente cuándo se ejecutará el constructor de la clase interna MyCustomization durante todo el procedimiento de construcción de la clase AutogenCls.

  2. Si será necesario implementar una interfaz IDiposable para que la clase MyCustomization maneje correctamente la eliminación de los recursos no administrados de la clase MyCustomization, no sé (todavía) cómo activar el método MyCustomization.Dispose () sin tocar el archivo AutogenCls.cs ... (pero como dije ''todavía'' :)

Pero este enfoque ofrece una gran separación del código generado automáticamente: la personalización completa está separada en diferentes archivos de códigos src.

disfrutar :)


Nada en lo que pueda pensar La "mejor" forma en que se me ocurre es agregar un ctor con un parámetro ficticio y usar eso:

public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol { public override MyWebService(int dummy) { string myString = "overridden constructor"; //other code... } } MyWebService mws = new MyWebService(0);


No puedes hacer esto. Sugiero usar un método parcial para el que luego puedes crear una definición. Algo como:

public partial class MyClass{ public MyClass(){ ... normal construction goes here ... AfterCreated(); } public partial void OnCreated(); }

El resto debería ser bastante auto explicativo.

EDITAR:

También me gustaría señalar que debe definir una interfaz para este servicio, que luego puede programar, para que no tenga que tener referencias a la implementación real. Si hicieras esto, tendrías algunas otras opciones.


Para un proxy de servicio web generado por Visual Studio, no puede agregar su propio constructor en la clase parcial (así puede hacerlo, pero no se llama). En su lugar, puede usar el atributo [OnDeserialized] (o [OnDeserializing]) para enganchar su propio código en el punto donde se crea una instancia de la clase de proxy web.

using System.Runtime.Serialization; partial class MyWebService { [OnDeserialized] public void OnDeserialized(StreamingContext context) { // your code here } }


Tuve un problema similar, con mi código generado creado por un archivo dbml (estoy usando clases Linq-to-SQL).

En la clase generada llama a un vacío parcial llamado OnCreated () al final del constructor.

Para resumir, si quiere conservar las cosas importantes del constructor que la clase generada hace por usted (que probablemente debería hacer), entonces en su clase parcial cree lo siguiente:

partial void OnCreated() { // Do the extra stuff here; }