Domanda

Ok, so cosa stai pensando "Perché scrivere un metodo che non vuoi che le persone usino?" Giusto?

Bene, in breve, ho una classe che deve essere serializzata in XML.Affinché il XmlSerializer per fare la sua magia, la classe deve avere un costruttore vuoto predefinito:

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

Quindi, ho bisogno di averlo, ma non voglio che le persone lo facciano utilizzo esso, così esiste qualche attributo che può essere utilizzato per contrassegnare il metodo come "NON UTILIZZARE"?

Stavo pensando di usare il Obsoleto attributo (poiché questo può interrompere la compilazione), ma sembra un po' "sbagliato", esiste un altro modo per farlo o devo andare avanti e stringere i denti?:)

Aggiornamento

OK, ho accettato la risposta di Keith, poiché immagino nel profondo del mio cuore di essere totalmente d'accordo.Questo è il motivo per cui ho posto la domanda in primo luogo, non mi piace l'idea di avere il file Obsoleto attributo.

Tuttavia...

È è ancora un problema, anche se riceviamo una notifica in IntelliSense, idealmente vorremmo interrompere la build, quindi esiste un modo per farlo?Forse creare un attributo personalizzato?

È stata creata una domanda più mirata Qui.

È stato utile?

Soluzione

Se una classe è [Serialisable] (cioè.può essere copiato ovunque secondo necessità) per deserializzare è necessario il costruttore senza parametri.

Immagino che tu voglia forzare l'accesso del tuo codice per passare i valori predefiniti per le tue proprietà a un costruttore con parametri.

Fondamentalmente stai dicendo che va bene per il XmlSerializer per fare una copia e quindi impostare le proprietà, ma non vuoi che lo faccia il tuo codice.

In una certa misura penso che questo sia un eccesso di progettazione.

Basta aggiungere commenti XML che descrivono in dettaglio quali proprietà devono essere inizializzate (e cosa).

Non utilizzare [Obsolete], perché non lo è.Riservatelo a metodi veramente deprecati.

Altri suggerimenti

Puoi usare:

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

in modo che non venga visualizzato in Intellisence.Se il consumatore desidera ancora utilizzarlo, può farlo, ma non sarà così rilevabile.

Tuttavia, il punto di Keith sull'ingegneria è ancora valido.

Ho letto il titolo e ho subito pensato "attributo obsoleto".Che ne dite di

    /// <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) { 
    ....

In realtà sarei propenso a non essere d'accordo con tutti coloro che sostengono l'uso di ObsoleteAttribute poiché la documentazione MSDN afferma che:

Contrassegnare un elemento come obsoleto informa gli utenti che l'elemento verrà rimosso nelle versioni future del prodotto.

Poiché i costruttori generici per la serializzazione XML non devono essere rimossi dall'applicazione, non li applicherei nel caso in cui uno sviluppatore di manutenzione lungo la strada non abbia familiarità con il funzionamento della serializzazione XML.

In realtà sto usando Quello di Keith metodo di notare semplicemente che il costruttore viene utilizzato per la serializzazione nella documentazione XML in modo che venga visualizzato in Intellisense.

Potresti costruirne uno tuo Attribute classe derivata, diciamo NonCallableAttribute per qualificare i metodi, quindi aggiungere all'attività di analisi del codice build/CI il controllo per monitorare se qualche codice utilizza tali metodi.

A mio parere, non puoi davvero costringere gli sviluppatori a non utilizzare il metodo, ma potresti rilevare quando qualcuno ha infranto la regola il prima possibile e risolverlo.

Wow, questo problema dà fastidio anche a me.

Sono inoltre necessari costruttori predefiniti per NHibernate, ma voglio forzare le persone a NON utilizzare gli inizializzatori di oggetti C# 3.0 in modo che le classi passino attraverso il codice del costruttore.

throw new ISaidDoNotUseException();

Separa il tuo oggetto serializzabile dal tuo oggetto di dominio.

Quello che stai cercando è il ObsoleteAttribute classe:

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 probabilmente funzionerà nella tua situazione: potresti persino causare l'interruzione della build se viene utilizzato questo metodo.

Poiché gli avvisi di obsoleto si verificano in fase di compilazione e poiché la riflessione necessaria per la serializzazione avviene in fase di esecuzione, contrassegnare il metodo come obsoleto non interromperà la serializzazione, ma avviserà gli sviluppatori che il metodo non è disponibile per essere utilizzato.

Sto usando il ObsoleteAttribute.

Ma puoi anche avere qualche commento, ovviamente.

E infine rimuovilo completamente se puoi (non è necessario mantenere la compatibilità con qualcosa di vecchio).Questo è il modo migliore.

Sì, c'è.

Ho scritto questo post sul blog a riguardo Lavorare con il designer.

Ed ecco il codice:


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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top