2013-02-10 22 views
6

Recentemente ho scritto alcuni oggetti serializzabili che trattano anche di una logica specifica e hanno un ciclo di vita specifico. Perché funzioni correttamente, deve essere istanziato con un costruttore appropriato, che accetta argomenti obbligatori. Per scopi di serializzazione, tuttavia, devo anche aggiungere un costruttore pubblico predefinito.È buona norma utilizzare l'attributo [Obsoleto] per indicare agli sviluppatori di non utilizzare parti di un'API

L'oggetto sarà disponibile pubblicamente dalla nostra API e gli sviluppatori di terze parti dovrebbero essere in grado di creare un'istanza e di utilizzarlo. Sebbene ci sia una documentazione appropriata su come manipolare correttamente con quell'oggetto, non è certo che qualcuno sarà tentato di usare il costruttore errato - e quindi avere problemi.

Sto cercando un modo pulito per applicare alcune indicazioni mentre gli sviluppatori di terze parti stanno scrivendo il loro codice. L'attributo Obsolete mi è venuto in mente: potevo annotare il costruttore di serializzazione con un commento appropriato come messaggio. Il messaggio apparirà quindi nelle avvertenze di uscita e indirizzerà lo sviluppatore sulla giusta riga di codice. Inoltre, l'utilizzo del costruttore verrà opportunamente evidenziato da Visual Studio e da qualsiasi componente aggiuntivo di controllo del codice utilizzato.

Ciò che mi infastidisce in questo approccio è che lo scopo dell'attributo Obsolete è molto diverso. Il suo significato semantico è che l'oggetto decorato è deprecato e probabilmente verrà rimosso in altre versioni. Nello scenario del serialization constructor questo è sbagliato e ci sarà una discrepanza tra l'uso e il significato di questo attributo. Per non parlare dell'opzione "trattare gli avvertimenti come errori" che potrebbero essere abilitati in alcuni reparti di sviluppo ...

Quindi, la domanda è: è una pratica accettabile per tale uso dell'attributo? Ci sono altri modi legali e universali per ottenere lo stesso effetto (per universale intendo non affidarmi a componenti aggiuntivi per l'ispezione del codice di terze parti e così via). Non controllo chi utilizza il codice e quale è la loro configurazione)?


Per quanto riguarda i commenti nel risposta qui sotto, (che è ancora utile per me), devo chiarire che sto usando un costruttore di default protetto su una classe ereditabile. Il costruttore è lì per supportare la serializzazione XML, ma non dovrebbe essere usato per inizializzare la classe nella logica di business. Le classi ereditanti dovrebbero chiamare alcuni degli altri costruttori di base e gli sviluppatori che scrivono le classi ereditate devono saperlo. Tuttavia, gli sviluppatori che derivano da questo codice devono anche avere i mezzi per abilitare la serializzazione XML per le loro classi ereditate, se necessario.

+4

Non è proprio la stessa cosa, ma utilizzando il [EditorBrowsable (EditorBrowsableState.Never)] nasconderà il costruttore da intellisense per evitare uno sviluppatore di farlo come un suggerimento e di utilizzarlo per sbaglio senza controllare la documentazione. – fsimonazzi

+0

@fsimonazzi, grazie per le informazioni utili. Allo stesso modo, nessuno può impedire a un membro obsoleto di accedere al codice utente, quindi il tuo suggerimento è abbastanza valido e più specifico. –

risposta

3

Hm, non penso che questa sia una buona soluzione. Tuttavia, hai davvero bisogno di un costruttore predefinito?

Si noti che l'API di serializzazione ha metodi per creare istanze non inizializzate senza utilizzare un costruttore (vedere MSDN: FormatterServices.GetUninitializedObject).

Inoltre, il normale costruttore di serializzazione personalizzata non è un costruttore predefinito ma uno che utilizza un SerializationInfo e uno StreamingContext. Se si dispone di una serializzazione personalizzata, si potrebbe anche essere in grado di risolvere il problema rendendo il costruttore predefinito interno e applicare un InternalsVisibleToAttribute per l'assembly che esegue la serializzazione.

+1

Per chiarire il problema della deserializzazione, stavo indirizzando non il binario (predefinito), ma la serializzazione XML che fa parte del framework .NET. Ha bisogno del costruttore senza parametri. Il costruttore non è necessario per essere "pubblico", ma se la classe deve essere ereditata e deve conservare le capacità di serializzazione, il costruttore dovrebbe essere almeno "protetto" (a meno che, naturalmente, alcuni degli altri costruttori non funzionino per te, ma questo non è un caso del problema della domanda). –

Problemi correlati