有没有更好的方法来写这个?也许是一类,而不是两类。
using System;
namespace SnippetTool.Repositories
{
public abstract class ARepository<TProvider> where TProvider : class
{
protected TProvider Provider { get; set; }
protected ARepository(TProvider provider)
{
if (provider == null)
throw new ArgumentNullException("provider");
Provider = provider;
}
}
public abstract class ARepository<TProvider, TValidator> : ARepository<TProvider> where TProvider : class where TValidator : class
{
protected TValidator Validator { get; set; }
protected ARepository(TProvider provider, TValidator validator) : base(provider)
{
Validator = validator;
}
}
}
答案 0 :(得分:11)
我认为你不能把它作为一个类来做,目前,我在这种情况下尝试做的一般是创建最通用的类(采用最通用的args)来拥有所有的逻辑,然后使更具体的是默认这些类型的子类。
例如,假设我们正在编写一个从一种类型的值转换为另一种类型的翻译器,所以像Dictionary
一样,但也有默认值等。
我们可以将其定义为:
public class Translator<TKey, TValue, TDictionary> where TDictionary : IDictionary<TKey, TValue>, new();
{
private IDictionary<TKey, TValue> _map = new TDictionary();
...
}
这是我的一般情况,可以有IDictionary
的任何实现,但是我们想要一个更简单的版本,如果没有指定,总是使用Dictionary
,我们可以这样做:
public class Translator<TKey, TValue> : Translator<TKey, TValue, Dictionary<TKey, TValue>>
{
// all this does is pass on the "default" for TDictionary...
}
通过这种方式,我可以做到:
// uses Dictionary<int, string>
var generic = new Translator<int, string>();
// uses SortedDictionary instead
var specific = new Translator<int, string, SortedDictioanry<int, string>>();
所以在你的情况下,也许你的泛型总是有一个TValidator属性,但它是默认的(也许总是以你最通用的形式返回true
?
例如,您可能有一个默认验证器的定义(比如称为DefaultValidator
),您可以反转您的定义,以便更通用(采用更多通用类型参数的那个) )具有所有逻辑和任何特化(较少的类型参数)只是默认这些额外类型的子类:
using System;
namespace SnippetTool.Repositories
{
public class DefaultValidator
{
// whatever your "default" validation is, may just return true...
}
public abstract class ARepository<TProvider> : ARepository<TProvider, DefaultValidator>
where TProvider : class
{
protected ARepository(TProvider provider) : base(provider, new DefaultValidator());
{
}
// needs no new logic, just any specialized constructors...
}
public abstract class ARepository<TProvider, TValidator>
where TProvider : class
where TValidator : class
{
public TValidator Validator { get; set; }
protected ARepository(TProvider provider, TValidator validator)
{
Provider = provider;
Validator = validator;
}
// all the logic goes here...
}
}
更新:是的,根据您的评论,如果TValidator
是加载项(而不是默认),那么就像你一样分层做得合适。