Как заменить перечисление чем-то вроде идентификатора интерфейса?
-
14-11-2019 - |
Вопрос
Пожалуйста, обратите внимание на следующие интерфейсы:
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 избыточно.Есть ли способ использовать что-то вроде идентификатора интерфейса вместо типа перечисления?
Любые комментарии по дизайну интерфейса приветствуются.
Решение
Это действительно зависит от того, что вы пытаетесь выполнить, но я один варианты вы можете посмотреть, использует универсальные, так что 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>();
}
. Другие советы
Обычно лучше написать что-то вроде этого:
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
цепочки, которые вам следует рассмотреть, чтобы вставить метод в уже существующую иерархию классов или создать новую.Вам следует стремиться писать код, похожий на тот, который вы видите в первом фрагменте кода.
Как обычно, это общий вариант, поэтому он может не подойти к вашей конкретной проблеме.
Я думаю, что точка здесь, что возвращенный список содержит «базовые» объекты.
Если вам это не нравится, вы можете создать некоторые перегрузки, такие как
IList<IAudioFile> GetAudioFiles();
IList<IVideoFile> GetVideoFiles();
.