Questo modello può essere usato con buoni risultati, ma questo non sembra un esempio. Un buon esempio potrebbe essere quello di comunicare vincoli semantici / garanzie che altrimenti non cambiano l'API. Ad esempio, potresti avere un'interfaccia che rappresenta un tipo di operazione e un'interfaccia secondaria che indica che l'operazione è idempotente. Quindi restituire un IIdempotentOperation
indica garanzie (previste) al consumatore e ricevere IIdempotentOperation
indica ulteriori vincoli all'utente.
Ma devi avere qualcosa di cui parlare. Se l'interfaccia non ha (direttamente o indirettamente) alcun metodo, allora sta dicendo qualcosa sui metodi su tutti gli oggetti, ad es. Equals
, o sta dicendo che l'oggetto è uno di un insieme di classi fisse e conosciute ai fini del type-casing tramite instanceof
o simili. Forse questa è l'idea, ma poi è abbastanza brutto. Se non si fa riferimento a una situazione come quella di cui sopra, non c'è assolutamente alcun motivo per cui i parametri non siano completamente parametrici e non dice nulla per implementare tale interfaccia.
Dovrei chiarire che è ITaskId
che sembra completamente inutile per me. Posso vedere che cosa ITask<>
sta cercando di ottenere. Sarebbe necessario più contesto per stabilire se tali interfacce stanno aggiungendo valore. Ad eccezione degli scenari che ho descritto sopra, non c'è letteralmente alcuna differenza tra class Foo
e class Foo : ITaskId
. Allo stesso modo, avere un parametro di un metodo di tipo ITaskId
non è diverso dall'avere un parametro di tipo Object
(o, preferibilmente, astrarlo in un parametro di tipo generico). Semplicemente non c'è alcun vincolo semantico che sia persino informalmente espressivo perché non ci sono metodi per limitare. Di nuovo, a meno che non indichi in modo informale un vincolo su un metodo come Equals
o ToString
, semplicemente non c'è un comportamento per vincolare un vincolo. Direi anche che non è solo inutile avere il vincolo ITaskId
, ad es. su TId
, ma in realtà è un errore. Puoi sempre vincolare il parametro di tipo TId
in qualsiasi uso particolare se necessario, ma può essere utile consentire a TId
di essere tipi che non implementano ITaskId
, come String
, anche se solo durante un intermediario calcolo. La comunità Haskell si è imbattuta nei problemi di vincoli non necessari che limitano la flessibilità in modo doloroso con l'esempio più notevole essendo il tipo Complex
che utilizzato per essere limitato ma ora non è (e in effetti il la funzione della lingua che consente di rimuovere i vincoli in tali posizioni poiché erano sempre non necessari).