【发布时间】:2016-05-06 12:31:49
【问题描述】:
我正在编写一个通用代码,用于处理从多个来源加载数据的情况。我有一个带有以下签名的方法:
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。
是否可以在 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);
}
然后扩展只是根据一些逻辑调用这两个方法。我必须指定类型,因为我需要访问每个特定实现的属性,所以我需要协方差。
【问题讨论】:
-
如果您的方法签名是
IDatabaseConfigurable<TContract, TSection> LoadFromAnySource(this TSection section, string serviceBaseUri, string nodeName, Func<TContract> contractCreator)(或只是TContract contract),则可以从用法中推断出类型。 -
这怎么违反了 DRY 原则?这比“不要重复写同一件事”要复杂一些。你可能不在乎你在
twitter中写了三遍t,是吗? :D 两者不相同 - 一个比另一个更通用。无论如何,@JeroenMostert 的评论几乎是最好的方法,应该完全是一个答案。虽然可能像程序员这样的地方而不是 SO - 我认为这对 SO 来说不是一个好问题,真的。 -
@JeroenMostert 是的,但他们不知道要使用哪个
IDatabaseConfigurable。 -
是的,对不起,显然我的意思是
Func<IDatabaseConfigurable<...>>。 “有效”结果是实现接口的结果——如果需要更多的东西,那么设计就有问题。 (事实上,我很确定设计存在问题,需要进行一些重构,但这并不完全是主题。) -
“错误”太强了。我只是说您可能可以以一种类型推断将隐式工作的方式构造您的代码(或者您应该使用较少的泛型)。这是否真的可行,以及您是否想要结果是完全不同的事情。如果不进一步深入研究您的代码,我无法有意义地回答这些问题,但这会退化为设计讨论,这是主观的并且明确不是 Stack Overflow 是关于什么的。你从字面上问的问题(“我能以某种方式避免用我所拥有的东西做这件事吗”)的答案是不,简单明了。