Error de diseño indicado por FxCop, y Cómo sellar un método para no ser heredado.

07/12/2003 - 23:42 por Néstor Marcel Sánchez Ahumada | Informe spam
Hola a todos:
Días atrás bajé el utilitario FxCop (desde
http://www.gotdotnet.com/team/fxcop/ ) el cual es una herramienta para
analizar ensamblados y determinar su conformancia con las guías de diseño
del .NET Framework.

Al analizar mis ensamblados de una aplicación windowsform, me mostró varios
errores, la mayoría referentes a nomenclatura de identificadores y cosas no
tan importantes. Pero hubo uno que me llamó la atención, que decía:
"Constructors should not call virtual methods defined by the class"

Tal mensaje se refería a una llamada a un método que llamé NotificaConsola
de la misma clase. Para el cual entrega la siguiente explicación:
"Virtual methods defined on the class should not be called from
constructors. If a derived class has overridden the method, the derived
class version will be called (before the derived class constructor is
called)."

Lo cual me parece bastante lógico. Pero me surgieron las siguientes dudas:

1) ¿Porqué me reclamó con mi método (el cual además implementa a uno de
interfaz) y no reclamó con el típico InitializeComponent ya que éste también
es llamado en el constructor? Eso me llevó a pensar que al ser mi método
implementador de un método de interfaz... entonces algún efecto secundario
tendría tal implementación. Pero si es así: ¿está documentado en alguna
parte?

2) ¿Cómo puedo hacer para evitar que un descendiente sobreescriba (override)
mi método? Porqué según dice la documentación podría marcar el método como
"sealed" (para lo cual tendría que declararlo así como "sealed override
public int NotificaConsola(string mensaje)".
Pero el compilador (versión 7.00.9466) no me lo permite (?!) ya que me dice:
"error CS0115: 'cdmSRV.cdmSRV.NotificaConsola(string)': no se encontr¢
ning£n miembro adecuado que reemplazar"
Lo cual deduzco que es por el "override" pero este es necesario para indicar
"sealed".
¿Y ENTONCES COMO INDICO QUE NO QUIERO QUE UN METODO DE CLASE BASE PUEDA SER
SOBREESCRITO????s

Si alguien puede ayudarme... lo agradeceré.
Saludos,

Néstor

Preguntas similare

Leer las respuestas

#1 Tomas Restrepo \(MVP\)
08/12/2003 - 00:16 | Informe spam
Hola Nestor,

Días atrás bajé el utilitario FxCop (desde
http://www.gotdotnet.com/team/fxcop/ ) el cual es una herramienta para
analizar ensamblados y determinar su conformancia con las guías de diseño
del .NET Framework.

Al analizar mis ensamblados de una aplicación windowsform, me mostró


varios
errores, la mayoría referentes a nomenclatura de identificadores y cosas


no
tan importantes. Pero hubo uno que me llamó la atención, que decía:
"Constructors should not call virtual methods defined by the class"

Tal mensaje se refería a una llamada a un método que llamé NotificaConsola
de la misma clase. Para el cual entrega la siguiente explicación:
"Virtual methods defined on the class should not be called from
constructors. If a derived class has overridden the method, the derived
class version will be called (before the derived class constructor is
called)."

Lo cual me parece bastante lógico. Pero me surgieron las siguientes dudas:

1) ¿Porqué me reclamó con mi método (el cual además implementa a uno de
interfaz) y no reclamó con el típico InitializeComponent ya que éste


también
es llamado en el constructor? Eso me llevó a pensar que al ser mi método
implementador de un método de interfaz... entonces algún efecto secundario
tendría tal implementación. Pero si es así: ¿está documentado en alguna
parte?



InitializeComponent() no es virtual por defecto. Tu método si lo es ya que
es implementación de una interfaz, y dichos métodos siempre son virtuales,
así no estén explicitamente marcados como tales.


2) ¿Cómo puedo hacer para evitar que un descendiente sobreescriba


(override)
mi método? Porqué según dice la documentación podría marcar el método como
"sealed" (para lo cual tendría que declararlo así como "sealed override
public int NotificaConsola(string mensaje)".
Pero el compilador (versión 7.00.9466) no me lo permite (?!) ya que me


dice:
"error CS0115: 'cdmSRV.cdmSRV.NotificaConsola(string)': no se encontr¢
ning£n miembro adecuado que reemplazar"
Lo cual deduzco que es por el "override" pero este es necesario para


indicar
"sealed".
¿Y ENTONCES COMO INDICO QUE NO QUIERO QUE UN METODO DE CLASE BASE PUEDA


SER
SOBREESCRITO????s



Para que no pueda ser sobreescrito debes marcarlo como sealed y como virtual
(ya que en tu caso. No puedes marcarlo override, porque en si mismo el
método no estaba siendo sobreescribiendo ningun otro metodo.

Tomas Restrepo

Respuesta Responder a este mensaje
#2 Néstor Marcel Sánchez Ahumada
08/12/2003 - 02:22 | Informe spam
Tomás:
No puedo marcarlo "virtual sealed" porque para marcarlo "sealed" debo
también marcarlo "override" y esto no se puede por dos causas:
1) No puedo marcar override un método virtual o new.
2) No puedo marcar override un método de clase base.
Creo que simplemente no se puede, quizás tengamos que esperar hasta el C#
3.0 para que el lenguaje soporte métodos base no sobreescribilbes (porque ya
ví la especificación 2.0 y tampoco lo contempla)
Gracias de todas formas,

Néstor.

"Tomas Restrepo (MVP)" wrote in message
news:Ol#
Hola Nestor,

> Días atrás bajé el utilitario FxCop (desde
> http://www.gotdotnet.com/team/fxcop/ ) el cual es una herramienta para
> analizar ensamblados y determinar su conformancia con las guías de


diseño
> del .NET Framework.
>
> Al analizar mis ensamblados de una aplicación windowsform, me mostró
varios
> errores, la mayoría referentes a nomenclatura de identificadores y cosas
no
> tan importantes. Pero hubo uno que me llamó la atención, que decía:
> "Constructors should not call virtual methods defined by the class"
>
> Tal mensaje se refería a una llamada a un método que llamé


NotificaConsola
> de la misma clase. Para el cual entrega la siguiente explicación:
> "Virtual methods defined on the class should not be called from
> constructors. If a derived class has overridden the method, the derived
> class version will be called (before the derived class constructor is
> called)."
>
> Lo cual me parece bastante lógico. Pero me surgieron las siguientes


dudas:
>
> 1) ¿Porqué me reclamó con mi método (el cual además implementa a uno de
> interfaz) y no reclamó con el típico InitializeComponent ya que éste
también
> es llamado en el constructor? Eso me llevó a pensar que al ser mi método
> implementador de un método de interfaz... entonces algún efecto


secundario
> tendría tal implementación. Pero si es así: ¿está documentado en alguna
> parte?

InitializeComponent() no es virtual por defecto. Tu método si lo es ya que
es implementación de una interfaz, y dichos métodos siempre son virtuales,
así no estén explicitamente marcados como tales.

>
> 2) ¿Cómo puedo hacer para evitar que un descendiente sobreescriba
(override)
> mi método? Porqué según dice la documentación podría marcar el método


como
> "sealed" (para lo cual tendría que declararlo así como "sealed override
> public int NotificaConsola(string mensaje)".
> Pero el compilador (versión 7.00.9466) no me lo permite (?!) ya que me
dice:
> "error CS0115: 'cdmSRV.cdmSRV.NotificaConsola(string)': no se encontr¢
> ning£n miembro adecuado que reemplazar"
> Lo cual deduzco que es por el "override" pero este es necesario para
indicar
> "sealed".
> ¿Y ENTONCES COMO INDICO QUE NO QUIERO QUE UN METODO DE CLASE BASE PUEDA
SER
> SOBREESCRITO????s

Para que no pueda ser sobreescrito debes marcarlo como sealed y como


virtual
(ya que en tu caso. No puedes marcarlo override, porque en si mismo el
método no estaba siendo sobreescribiendo ningun otro metodo.

Tomas Restrepo



email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida