Я пишу общий код, который должен обрабатывать ситуации, когда данные загружаются из нескольких источников. У меня есть метод со следующей подписью:
public static TResult LoadFromAnySource<TContract, TSection, TResult>
(this TSection section,
string serviceBaseUri,
string nodeName)
where TSection : ConfigurationSection
where TResult : IDatabaseConfigurable<TContract, TSection>, new()
where TContract : new()
Но это перебор: когда я прохожу TResult
, я уже знаю, что именно есть TContract
и TSection
. В моем примере:
public interface ISourceObserverConfiguration
: IDatabaseConfigurable<SourceObserverContract, SourceObserverSection>
Но я должен написать следующее:
sourceObserverSection.LoadFromAnySource<SourceObserverContract,
SourceObserverSection,
SourceObserverConfiguration>
(_registrationServiceConfiguration.ServiceBaseUri, nodeName);
Вы можете видеть, что я должен указать пару <SourceObserverContract, SourceObserverSection>
дважды, это нарушение DRY принципа. Поэтому я хотел бы написать что-то вроде:
sourceObserverSection.LoadFromAnySource<SourceObserverConfiguration>
(_registrationServiceConfiguration.ServiceBaseUri, nodeName);
и сделать SourceObserverContract
и SourceObserverSection
вывод из интерфейса.
Возможно ли это в С#, или я должен указывать его везде вручную?
IDatabaseConfigurable
выглядит следующим образом:
public interface IDatabaseConfigurable<in TContract, in TSection>
where TContract : ConfigContract
where TSection : ConfigurationSection
{
string RemoteName { get; }
void LoadFromContract(TContract contract);
void LoadFromSection(TSection section);
}
Затем расширение просто вызывает эти два метода на основе некоторой логики. Я должен указать типы, потому что мне нужно получить доступ к свойствам каждой конкретной реализации, поэтому мне нужна ковариация.