Is there a better way to write this? As one class perhaps, instead of two.
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;
}
}
}
I don’t think you can do it as one class, currently, generally what I try to do in this situation is create the most general class (the one that takes the most generic args) to have all the logic, then make the more specific ones be subclasses that default those types.
For example, let’s say we are writing a translator that translates from one type of value to another, so like a
Dictionarybut also has defaults, etc.We could define this as:
This is my generic case, which can have any implementation of
IDictionary, but say we want a simpler version that always usesDictionaryif not specified, we could do:In this way, I can make:
So in your case, maybe your generic always has a TValidator property, but it’s defaulted (maybe to always return
truein your most generic form?For example, maybe you have a definition of a default validator (say called
DefaultValidator) you could reverse your definitions so that the more generic (the one that takes more generic type parameters) has all the logic and any specializations (fewer type parameters) are just subclasses that default those extra types:UPDATE: Yes, based on your comment, if the
TValidatoris an add-on (and not something defaulted), then layering it like you did is appropriate.