Pregunta

Ok, sé lo que estás pensando: "¿Por qué escribir un método que no quieres que la gente use?" ¿Bien?

Bueno, en resumen, tengo una clase que necesita serializarse a XML.Para que el XmlSerializer Para hacer su magia, la clase debe tener un constructor vacío predeterminado:

public class MyClass
{
  public MyClass()
  {
    // required for xml serialization
  }
}

Entonces necesito tenerlo, pero no quiero que la gente lo tenga. usar así es ¿Existe algún atributo que pueda usarse para marcar el método como "NO USAR"?

Estaba pensando en usar el Obsoleto atributo (ya que esto puede detener la compilación), pero eso parece un poco "incorrecto", ¿hay alguna otra forma de hacerlo o tengo que seguir adelante y hacer de tripas corazón?:)

Actualizar

Bien, he aceptado la respuesta de Keith, ya que supongo que en el fondo de mi corazón estoy totalmente de acuerdo.Por eso hice la pregunta en primer lugar, no me gusta la idea de tener el Obsoleto atributo.

Sin embargo...

Allá es Sigue siendo un problema, mientras nos notifican en Intellisense, idealmente nos gustaría interrumpir la compilación, entonces, ¿hay alguna forma de hacerlo?¿Quizás crear un atributo personalizado?

Se ha creado una pregunta más enfocada. aquí.

¿Fue útil?

Solución

Si una clase es [Serialisable] (es decir.se puede copiar en el lugar según sea necesario) se necesita el constructor sin parámetros para deserializar.

Supongo que desea forzar el acceso de su código para pasar los valores predeterminados de sus propiedades a un constructor parametrizado.

Básicamente estás diciendo que está bien para el XmlSerializer para hacer una copia y luego establecer propiedades, pero no desea que su propio código lo haga.

Hasta cierto punto creo que esto es un diseño excesivo.

Simplemente agregue comentarios XML que detallen qué propiedades deben inicializarse (y cuáles).

no usar [Obsolete], porque no lo es.Reserve eso para métodos realmente obsoletos.

Otros consejos

Puedes usar:

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Nunca)]

para que no aparezca en Intellisence.Si el consumidor aún quiere usarlo, puede hacerlo, pero no será tan reconocible.

Sin embargo, el punto de Keith sobre la ingeniería excesiva sigue en pie.

Leí el título e inmediatamente pensé "atributo obsoleto".Qué tal si

    /// <summary>
    /// do not use
    /// </summary>
    /// <param name="item">don't pass it anything -- you shouldn't use it.</param>
    /// <returns>nothing - you shouldn't use it</returns>
    public bool Include(T item) { 
    ....

De hecho, me inclinaría a no estar de acuerdo con todos los que defienden el uso de la ObsoleteAttribute como dice la documentación de MSDN que:

Marcar un elemento como obsoleto informa a los usuarios que el elemento se eliminará en futuras versiones del producto.

Dado que los constructores genéricos para la serialización XML no deben eliminarse de la aplicación, no los aplicaría en caso de que un desarrollador de mantenimiento en el futuro no esté familiarizado con cómo funciona la serialización XML.

De hecho he estado usando Keith's método de simplemente observar que el constructor se usa para la serialización en la documentación XML para que aparezca en Intellisense.

Podrías construir el tuyo propio Attribute clase derivada, digamos NonCallableAttribute para calificar los métodos y luego agregue a su tarea de análisis de código de compilación/CI la verificación para monitorear si algún código utiliza esos métodos.

En mi opinión, realmente no se puede obligar a los desarrolladores a no utilizar el método, pero se puede detectar cuando alguien infringe la regla lo antes posible y solucionarlo.

Vaya, ese problema también me molesta.

También necesita constructores predeterminados para NHibernate, pero quiero obligar a las personas a NO usar inicializadores de objetos C# 3.0 para que las clases pasen por el código del constructor.

throw new ISaidDoNotUseException();

Separe su objeto serializable de su objeto de dominio.

Lo que estás buscando es el ObsoleteAttribute clase:

using System;

public sealed class App {
   static void Main() {      
      // The line below causes the compiler to issue a warning:
      // 'App.SomeDeprecatedMethod()' is obsolete: 'Do not call this method.'
      SomeDeprecatedMethod();
   }

   // The method below is marked with the ObsoleteAttribute. 
   // Any code that attempts to call this method will get a warning.
   [Obsolete("Do not call this method.")]
   private static void SomeDeprecatedMethod() { }
}

ObsoleteAttribute probablemente funcionará en su situación; incluso puede hacer que la compilación se rompa si se utiliza ese método.

Dado que las advertencias de obsoleto ocurren en tiempo de compilación, y dado que la reflexión necesaria para la serialización ocurre en tiempo de ejecución, marcar ese método como obsoleto no interrumpirá la serialización, pero advertirá a los desarrolladores que el método no está ahí para ser utilizado.

estoy usando el ObsoleteAttribute.

Pero también puedes hacer algunos comentarios, por supuesto.

Y finalmente elimínelo por completo si puede (no es necesario mantener la compatibilidad con algo antiguo).Esa es la mejor manera.

Sí lo hay.

Escribí esta entrada de blog al respecto. Trabajando con el diseñador.

Y aquí está el código:


public class MyClass
{
  [Obsolete("reason", true)]
  public MyClass()
  {
    // required for xml serialization
  }
}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top