L'interfaccia eredita dall'interfaccia senza specificare un nuovo membro

0

È una specie di brutta progettazione avere qualcosa del genere:

public interface IFooStream
{
    long Length { get; }
    long Position {get; set;}
    //...
}

public interface IReadableFooStream<T> : IFooStream
{
    int Read(T[] buffer, int offset, int count);
}

public interface IByteStream : IReadableFooStream<byte>
{
}

public interface IFloatStream : IReadableFooStream<float>
{
}

Come risolverebbe qualcosa del genere? Devo assolutamente avere IByteStream e l'interfaccia IFloatStream.

    
posta Florian 13.12.2014 - 17:04
fonte

2 risposte

2

I definitely must have the IByteStream and the IFloatStream interface.

Senza una ragione convincente, sicuramente dico di no. Rendi un ByteList o un FloatList ? No, lasci List essere e consenti alle persone di impostarlo come parametro.

Questa sorta di alias può occasionalmente essere utile, ma più spesso è un odore di codice che la tua interfaccia / classe sia troppo astratta (o che faccia troppe cose). Stai permettendo che le cose siano parametrizzate all'n-esimo grado, e di solito non è necessario.

How would you solve something like this?

Nella mia esperienza, un IFooStream non è utile da solo. Vorrei creare un flusso di lettura, uno stream di scrittura e una combinazione maaaaybe con un'interfaccia di base se / quando trovo che ne ho effettivamente bisogno. Supponendo ovviamente che gli stream .NET siano in qualche modo incapaci di fornire l'interfaccia di cui ho bisogno per fare il lavoro ...

    
risposta data 13.12.2014 - 17:40
fonte
0

The IFooStream just connects both types since both got a length and a position,... But actually the IByteStream and the IFloatStream already exist as an essential part of the audio lib.

Suona come gli unici altri tipi nella lib che dipendono da IFooStream e IReadableFooStream<T> sono IByteStream e IFloatStream . Questi ultimi due sembrano quelli interessanti che usano il resto della lib. Se nessun altro tipo effettivamente dipende da IReadableFooStream<T> , ed è lì per motivi di ereditarietà, sono d'accordo che odori.

I really need them to know whether an implementation provides raw data or provides samples.

Quindi, perché non preferire la composizione sull'ereditarietà e chiamarli come sono?

public interface IProvideRawStream
{
    IFooStream Stream { get; }
    int Read(byte[] buffer, int offset, int count);
}

public interface IProvideSampleStream
{
    IFooStream Stream { get; }
    int Read(float[] buffer, int offset, int count);
}

... o, se la composizione non ha senso nell'API, cosa c'è di sbagliato nell'avere ereditarietà di un solo livello?

public interface IFooStream
{
    long Length { get; }
    long Position {get; set;}
    //...
}

public interface IProvideRawStream : IFooStream
{
    int Read(byte[] buffer, int offset, int count);
}

public interface IProvideSampleStream : IFooStream
{
    int Read(float[] buffer, int offset, int count);
}
    
risposta data 20.12.2014 - 08:44
fonte

Leggi altre domande sui tag