Esiste un nome per questo nella teoria dei tipi? Specificare che un valore soddisfa più interfacce senza specificare il tipo concreto

2

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.

    
posta Lukas Rieger 05.01.2016 - 20:08
fonte

2 risposte

4

Scala consente questo e chiama il tipo risultante un Tipo composto . Il tuo esempio sarebbe simile a questo in Scala:

def seekAndRead(stream: IReaderStream with ISeekable) {
    stream.seek(5) // OK
    stream.read(...) // OK
    stream.write(...) // Not OK
}

IReaderStream with ISeekable è il tipo composto.

Puoi anche dire che una variabile di tipo è un sottotipo di un tipo composto:

class UsesStreams[A <: IReaderStream with ISeekable] {
    // use variables of type A in here
}
    
risposta data 05.01.2016 - 21:09
fonte
-2

Crea una nuova interfaccia che implementa sia IEnumerable<string> che INotifyCollectionChanged in questo modo:

interface IBoth : IEnumerable<string>, INotifyCollectionChanged
{
}

Quindi il tuo metodo restituisce questa nuova interfaccia:

IBoth GetStringData() {
    return /* an object which implements both interfaces */;
}

Questo è tutto.

    
risposta data 05.01.2016 - 22:11
fonte

Leggi altre domande sui tag