Как заменить перечисление чем-то вроде идентификатора интерфейса?

Пожалуйста, рассмотрите следующие интерфейсы:

interface IFile
{
    // Members
};

interface IAudioFile : IFile
{
    // Members
};

interface IVideoFile : IFile
{
    // Members  
};

enum ContentType
{
    Audio,
    Video
};

interface IProvider
{
    HashSet<ContentType> GetSupportedTypes();
    IList<IFile> GetFiles(ContentType contentType);
};

Я думаю, что перечисление ContentType является избыточным. Есть ли способ использовать что-то вроде идентификатора интерфейса вместо типа перечисления?

Любые комментарии по дизайну интерфейса очень ценятся.

3 ответа

Решение

Это действительно зависит от того, чего вы пытаетесь достичь, но я могу обратить внимание на один из вариантов использования дженериков, чтобы IProvider был таким же

interface IProvider
{
    IList<IFile> GetFiles<T>() where T: IFile;
}

который может быть реализован так

public void ProviderConcrete()
{
    public IList<IFile> GetFiles<T>()
    {
        if(typeof(t) == typeof(IAudioFile))
            .... get Audio files

    }
}

и называется так

public void Caller()
{
    var files = GetFiles<IAudioFile>();
} 

Я думаю, что дело здесь в том, что возвращаемый список содержит "базовые" объекты.

Если вам это не нравится, вы можете создать некоторые перегрузки, такие как

IList<IAudioFile> GetAudioFiles();
IList<IVideoFile> GetVideoFiles();

Обычно лучше написать что-то вроде этого:

void method(IFile file) {
    file.DoYourThing();
}

чем

void method(ContentType id) {
   switch (id) {
   case ContentType.Audio: 
       file.DoThis();
       break;

   case ContentType.Video: 
       file.DoThat();
       break;
   }
}

Это связано с тем, что с течением времени коммутаторы обычно становятся кошмаром технического обслуживания, а также подвержены ошибкам.

Я рекомендую, что когда вам нужно switches или же if-else цепочки, которые вы должны рассмотреть, чтобы вставить метод в уже существующую иерархию классов или создать новую. Вы должны стремиться написать код, похожий на тот, который вы видите в первом фрагменте кода.

Как обычно, это общее, поэтому оно может не относиться к вашей конкретной проблеме.

Другие вопросы по тегам