Как заменить перечисление чем-то вроде идентификатора интерфейса?
Пожалуйста, рассмотрите следующие интерфейсы:
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
цепочки, которые вы должны рассмотреть, чтобы вставить метод в уже существующую иерархию классов или создать новую. Вы должны стремиться написать код, похожий на тот, который вы видите в первом фрагменте кода.
Как обычно, это общее, поэтому оно может не относиться к вашей конкретной проблеме.