c# - method - ¿Qué excepción lanzar cuando un establecedor de propiedades no está permitido?
inherits c# asp net (5)
Tengo una clase base que tiene una propiedad virtual:
public virtual string Name { get; set; }
luego tengo una clase derivada que anula solo al que obtiene la propiedad
public override string Name
{
get { return "Fixed Name"; }
}
El problema es que esto solo anula al getter. Si alguien llama al setter, se llamará al setter de clase base, y la persona que llama no sabrá que es ineficaz.
Así que pensé que haría algo como:
public override string Name
{
get { return "Fixed Name"; }
set { throw new Exception(); } //which exception type?
}
Así que dos (preguntas relacionadas):
- ¿Hay un patrón mejor para que yo use?
- Si debería usar el patrón anterior, ¿qué excepción usar?
Edición : Algunas razones por las que una excepción se preferiría sobre otra serían buenas. Mi compañero de trabajo y yo hemos tenido el mismo argumento entre NotSupported
e InvalidOperation
.
Aquí me gustaría ir para una NotImplementedException .
Lanzar la excepción NotSupportedException . Cita del enlace:
Existen métodos que no se admiten en la clase base, con la expectativa de que estos métodos se implementarán en las clases derivadas. La clase derivada podría implementar solo un subconjunto de los métodos de la clase base y lanzar la excepción NotSupportedException para los métodos no compatibles.
Mi opinión es que InvalidOperationException no es una opción correcta. Cita de MSDN:
La excepción que se produce cuando una llamada de método no es válida para el estado actual del objeto.
No hay nada sobre el estado actual en su situación. Es que el contrato de clase no soporta la operación.
Rompe el principio de sustitución de Liskov y por eso es una mala idea.
Si la clase base realmente permite establecer el nombre (en lugar de exponer un definidor abstracto que no se garantiza que funcione), las clases derivadas también deberían hacerlo. Si desea una jerarquía que incluya algunas clases donde se puede establecer el nombre y otras donde no, ambos tipos de clase deben heredar de una clase de ReadableXX
abstracta con una propiedad de Name
lectura-escritura no virtual que se encadena para abstraer los métodos GetName
y SetName
. También debe proporcionar algunos medios para indicar si se SetName
(por ejemplo, un método CanSetName
). Una variante de solo lectura de la clase podría definir una "nueva" propiedad de Name
solo lectura que se encadenaría a GetName
, y hacer que su reemplazo de nombre de conjunto lance NotSupportedException
. Si la especificación para la clase dice que SetName
solo funcionará si CanSetName
devuelve verdadero, entonces hacer que SetName
arroje una excepción en las clases donde CanSetName
devuelva falso no violaría el principio de sustitución de Liskov.
Si puede, puede intentar mover el definidor al constructor de la clase base y hacer que el definidor sea privado. O como Jon sugirió crear una clase / interfaz base abstracta con captadores que son compatibles con todas las implementaciones.
Esto evitaría toda la situación con el lanzamiento de la excepción.