I have some code like this:
public interface Base<TImpl, T1>
where TImpl : Base<TImpl, T1>
{
public T1 Build(TImpl arg);
}
public class Impl1 : Base<Impl1, int>
{
public int Value { get; set; }
public int Build(Impl1 arg)
{
return arg.Value;
}
}
public class Impl2 : Base<Impl2, string>
{
public string Value { get; set; }
public string Build(Impl2 arg)
{
return arg.Value;
}
}
The TImpl
generic argument seems quite ugly to me. Do I have a chance to safely remove the TImpl
part, or remove T1, T2...
and can write something like public TImpl.C1 Method(TImpl arg);
?
CodePudding user response:
This would be an example of Curiously recurring template pattern. It does not make much sense when there is only one implementing class.
The point of this pattern is to make sure that the argument to Impl.Method
is also Impl
. There would not be any simple way to avoid this pattern while supplying the same level of type-safety.
Eric Lippert, one of the architects behind C#, has an article on the subject where he points out that while the pattern have some potential uses, it also have problems (thanks to Matthew Watson for pointing it out). And conclude with:
My advice is to think very hard before you implement this sort of curious pattern in C#; do the benefits to the customer really outweigh the costs associated with the mental burden you’re placing on the code maintainers?
You could also always ignore type-safety and just take and return objects, but I would not recommend it.