Dichiarazione di non responsabilità: penso che le regole siano quasi le stesse nella maggior parte dei linguaggi OO, ma dato che sono più familiare con C #, mi riferirò a questo linguaggio specifico.
Penso che l'uso di attributi e riflessioni potrebbe essere ampiamente ridotto se i membri statici applicassero gli stessi principi delle istanze OO.
Le proprietà e i metodi statici possono essere "sovrascritti" dai decedent utilizzando la nuova parola chiave, ma non possono essere forzati ad implementarne uno tramite un'interfaccia, né la parola chiave 'base' può essere utilizzata (solo il nome di base è supportato esplicitamente ). Per peggiorare le cose, i membri non possono essere referenziati tramite un'istanza, ma devono sempre essere specificatamente qualificati con il tipo esatto.
I costruttori hanno anche un supporto limitato di "ereditarietà", si può scegliere quale costruttore di base è chiamato, ma non si può forzare un oggetto a supportare un costruttore che prende determinati parametri definendolo in un'interfaccia.
Il suggerimento migliore che ho trovato per rispondere a questa domanda è questo in overflow dello stack (risposta a una domanda diversa ).
Nella sua risposta Jörg indica tre principi che si applicano all'Object Orientation:
- Messaggi,
- conservazione locale e protezione e occultamento del processo dello stato e
- estrema rilegatura in ritardo di tutte le cose.
Ora capisco perfettamente che se vuoi passare una classe piena di stato da un metodo a un altro come un oggetto, questi principi hanno senso. Tuttavia, a mio parere, il principio di ereditarietà, i metodi di base prioritari con funzionalità alternative o aggiuntive potrebbero anche essere utili per la logica aziendale senza stato.
Un esempio in cui forzare un oggetto a implementare un determinato costruttore sarebbe utile è con la de-serializzazione. Ad esempio, dove il costruttore deve accettare un nodo XML. In C # è implementabile dinamicamente usando il reflection, ma avere errori in fase di compilazione ed evitare il boilerplate di riflessione aggiungerebbe molto valore!
Il metodo statico / interfacce membro sarebbe utile in situazioni in cui alcuni aspetti di un valore sono specifici del tipo, senza alcuna relazione con l'istanza. Ad esempio, una classe può avere un DisplayName, Unità, Peso, Fattore o altri aspetti che sono uguali in tutte le istanze del tipo specifico, indipendentemente dal valore dell'istanza. Gli attributi (o le annotazioni) possono essere utilizzati per sfruttarli senza la necessità di creare un'istanza, tuttavia, anche in questo caso è un codice aggiuntivo e non c'è modo di imporre l'implementazione con errori in fase di compilazione.
Ammetto che ci sono molti modi semplici per aggirare questi punti, non sto cercando soluzioni alternative. Restituire un valore statico in una proprietà di istanza è abbastanza comune, e non è tanto un overhead per creare un'istanza di un oggetto solo per leggere gli aspetti specifici del tipo, ma mi piacerebbe conoscere lo sfondo logico sul perché statico le cose sono state sistematicamente escluse. Ho già sentito parlare di "stack virtuale", ma non so come funziona tecnicamente (e non trovo alcuna spiegazione semplice in rete).
Le ragioni della natura tecnica o filosofica?
Modifica: elaborazione su interfacce statiche:
Un esempio di come penso che un'interfaccia statica possa fornire un controllo strongmente scritto, controllato, alternativo alla riflessione:
public staticInterface MyStaticInterface
{
constructor(XmlNode node);
string DisplayName { get; }
int Weight { get; }
}
L'utilizzo:
public void FillNodesToolBox()
{
MyStaticInterface[] nodes =
assembly.GetTypes().Where(t => t.Implements<MyStaticInterface>());
for (int i = nodes.Length - 1; i >= 0 ; i--)
{
Console.WriteLine(string.Concat(
nodes[i].DisplayName, " (", nodes[i].Weight.ToString(), ")"));
}
}
Guardando indietro, in realtà sembra che il mio oggetto Type sia ereditato da System.Type, aggiungendo alcune proprietà, che è diverso da un membro statico ...
string.Empty != typeof(string).Emty
(quest'ultimo non verrà compilato).
Forse sto iniziando a trovare la risposta, ma sembra che stia camminando in un cerchio paradossale, non è ancora abbastanza "istantaneo" ...