简体   繁体   中英

C# generic - Can I refer to an implement of an interface inside it?

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); ?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM