Tutti i miei progetti condividono la stessa libreria di base che ho accumulato da un po 'di tempo. Contiene utility e classi di helper statiche per aiutarli dove .NET non offre esattamente ciò che voglio. Originariamente tutti gli aiutanti erano scritti principalmente per servire a uno scopo interno e deve rimanere tale, ma a volte si rivelano molto utili per altre assemblee. Ora renderli pubblici in modo affidabile è più complicato di quanto la maggior parte potrebbe pensare, ad esempio tutti i metodi che assumono i tipi nullable ora devono contenere il controllo degli argomenti senza caricare le utilità interne al prezzo di farlo. Il prezzo potrebbe essere trascurabile, ma è tutt'altro che corretto.
Durante il refactoring, ho rivisto questo caso più volte e ho trovato le seguenti soluzioni finora:
-
Avere una classe interna e pubblica per ogni helper
La classe interna contiene il codice effettivo mentre la classe pubblica funge da punto di accesso che controlla gli argomenti.
Contro:- La classe interna richiede un prefisso per evitare l'ambiguità (la migliore presentazione dovrebbe essere riservata ai tipi pubblici)
- Non è possibile discriminare metodi che non richiedono il controllo degli argomenti
-
Avere una classe che contiene membri sia interni che pubblici (come implementato convenzionalmente in .NET framework).
All'inizio, questa potrebbe sembrare la migliore soluzione possibile, ma ha la stessa prima sgradevole truffa della soluzione 1.
Contro:- I metodi interni richiedono un prefisso per evitare l'ambiguità
- I metodi interni richiedono un prefisso per evitare l'ambiguità
-
Ha una classe interna implementata dalla classe pubblica che sostituisce tutti i membri che richiedono il controllo degli argomenti.
Contro:- È non statico, è necessaria almeno un'istanza. Questo non si adatta perfettamente all'idea della classe helper, dato che generalmente consiste di frammenti di codice indipendenti, non dovrebbe richiedere l'istanziazione.
- Anche i metodi non statici sono più lenti di un livello trascurabile, il che non giustifica realmente questa opzione.
C'è una conseguenza generale e inevitabile, un sacco di manutenzione è necessaria perché ogni membro interno richiederà una controparte pubblica.
Una nota sulla soluzione 1: La prima conseguenza può essere evitata inserendo entrambe le classi in spazi dei nomi diversi, ad esempio puoi avere il vero helper nel namespace root e l'helper pubblico in uno spazio dei nomi chiamato "Helpers".