Ho spesso desiderato la stessa funzione richiesta ad es. qui e in molti altre domande su SO:
Essere in grado di specificare che qualcosa soddisfa più interfacce senza specificare il tipo concreto.
es. in C # pseudo sintassi
(IEnumerable<string>, INotifyCollectionChanged) GetStringData() {
return /* an object which implements both interfaces */;
}
È possibile emulare questo parametro per i parametri del metodo usando generici, ma non per valori di ritorno, campi, proprietà, ecc.
Esiste un nome per questo nella teoria dei tipi che potrei usare per trovare maggiori informazioni a riguardo?
Esistono lingue (strongmente tipizzate) che implementano questo?
Un esempio in cui ciò potrebbe essere utile sarebbe un'implementazione immaginaria di Stream.
Attualmente esiste una classe astratta con molti metodi / proprietà e proprietà di controllo delle caratteristiche che abilitano / disabilitano la funzionalità.
Con questa funzione potresti avere molte interfacce IReadStream
, IWriteStream
, ISeekable
, IHasFixedLength
, ecc. e poi dire Ok, ho bisogno di qualcosa dove posso leggere e cercare, quindi prendo (IReadStream + ISeekable)
.
=============== (Troppo lungo per un commento)
Penso che il modo migliore per implementarlo in C # sia una combinazione di oggetti restituiti / cast esplicito e checker implementati con Roslyn che verificano il cast solo per le interfacce "consentite". per es.
[MultiReturn(typeof(IReaderStream), typeof(ISeekable))]
object GetSeekableReaderStream() {
var stream = new ConcreteReaderWriterSeekableStream();
// stream actually implements IReaderStream, ISeekable AND IWriterStream
// but I only want to expose the first two
return stream;
}
Potrebbe quindi essere usato come
var stream = GetSeekableReaderStream();
(stream as ISeekable).Seek(5); // OK
(stream as IReaderStream).Read(...); // OK
(stream as IWriterStream).Write(...); // legal for the compiler AND at runtime, but the custom analyzer would scream
Qualcosa di simile (ma diverso) che viene discusso qui a roslyn sarebbe "interfacce strutturali", ma sono simili al ducktyping, applicano solo i metodi specifici implementati, non che l'oggetto implementa interfacce specifiche. Ancora questo sarebbe "abbastanza vicino" che la maggior parte sarebbe possibile.