我正在编写一个通用代码,它应该处理从多个源加载数据的情况.我有一个带有以下签名的方法:
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()
Run Code Online (Sandbox Code Playgroud)
但它是一个矫枉过正:当我通过TResult,我已经知道什么TContract和TSection确切的.在我的例子中:
public interface ISourceObserverConfiguration
: IDatabaseConfigurable<SourceObserverContract, SourceObserverSection>
Run Code Online (Sandbox Code Playgroud)
但我必须写下面的内容:
sourceObserverSection.LoadFromAnySource<SourceObserverContract,
SourceObserverSection,
SourceObserverConfiguration>
(_registrationServiceConfiguration.ServiceBaseUri, nodeName);
Run Code Online (Sandbox Code Playgroud)
您可以看到我必须指定<SourceObserverContract, SourceObserverSection>两次对,这违反了DRY原则.所以我想写一些类似的东西:
sourceObserverSection.LoadFromAnySource<SourceObserverConfiguration>
(_registrationServiceConfiguration.ServiceBaseUri, nodeName);
Run Code Online (Sandbox Code Playgroud)
从界面制作SourceObserverContract和SourceObserverSection推断.
是否有可能在C#或我应该手动指定它?
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);
}
Run Code Online (Sandbox Code Playgroud)
然后扩展只是根据某些逻辑调用这两种方法.我必须指定类型,因为我需要访问每个特定实现的属性,所以我需要一个协方差.
不,你不能。类型推断不考虑方法的返回类型。TResult可能包含所需的所有信息,但类型推断不会使用它。
您需要制作TContract方法签名的一部分,以便可以推断类型。TResult是多余的,不需要通用,只需用作IDataBaseConfigurable<TContract, TSection>方法的返回类型即可。