title: Is it possible to constrain a generic parameter type to this?
body: <p><strong>Short version</strong></p>
  <p>How do I force the <code>BaseClass</code>'s <code>TModel</code> generic parameter to be of the same type as the class that derives from it?</p>
  <pre class="lang-cs prettyprint-override"><code>public class BaseClass&lt;TModel, TValidator&gt; where TValidator : IValidator&lt;TModel&gt; { }
  
  public class Person : BaseClass&lt;Person, PersonValidator&gt; { }
  </code></pre>
  <p>In this example, how do I force the <code>BaseClass</code>'s <code>TModel</code> to be of type <code>Person</code> and not something else?</p>
  <p>This is invalid syntax, but it's what I'm imagining:</p>
  <pre class="lang-cs prettyprint-override"><code>public class BaseClass&lt;TValidator&gt; where TValidator : IValidator&lt;this&gt; { }
  
  public class Person : BaseClass&lt;PersonValidator&gt; { }
  </code></pre>
  <p>Is this somehow possible or should I use a totally different solution to achieve this?</p>
  <p><strong>Long version</strong></p>
  <p>I'm trying to extract some validation logic into a base class, but I don't know how to constraint the generic types so the resulting base class is fully fool-proof.</p>
  <p>Here's an example of what all the validation logic looks like without a base class. I'm using FluentValidation to validate the object and I'm exposing that validation result via the <code>IDataErrorInfo</code> interface so it can be used by the WPF UI.</p>
  <p><strong>Original solution</strong></p>
  <pre class="lang-cs prettyprint-override"><code>public class User : IDataErrorInfo 
  {
      private readonly IValidator&lt;Person&gt; _validator = new();
  
      public string Username { get; set; }
      public string Password { get; set; }
  
      private string ValidateAndGetErrorForProperty(string propertyName)
      {
          var result = _validator.Validate(this);
  
          if (result.IsValid)
          {
              return string.Empty;
          }
  
          return result.Errors.FirstOrDefault(a =&gt; a.PropertyName == propertyName)?.ErrorMessage ?? string.Empty;
      }
  
      //IDataErrorInfo implementation
      public string Error =&gt; string.Empty;
      public string this[string columnName] =&gt; ValidateAndGetErrorForProperty(columnName);
  }
  
  public class UserValidator : AbstractValidator&lt;User&gt;
  {
      public UserValidator()
      {
          RuleFor(a =&gt; a.Username)
              .EmailAddress();
  
          RuleFor(a =&gt; a.Password)
              .MinimumLength(12);
      }
  }
  </code></pre>
  <p><strong>Validation implementation separated into a base class</strong></p>
  <p>I'd like to separate the validation logic and <code>IDataErrorInfo</code> implementation into a base class so this boilerplate doesn't have to be repeated in every model class. Here's what I have.</p>
  <pre class="lang-cs prettyprint-override"><code>public abstract class ValidationBase&lt;TModel, TValidator&gt; : IDataErrorInfo where TValidator : IValidator&lt;TModel&gt;, new()
  {
      private readonly TValidator _validator;
  
      public ValidationBase()
      {
          _validator = Activator.CreateInstance&lt;TValidator&gt;();
      }
  
      private string ValidateAndGetErrorForProperty(string propertyName)
      {
          //I have to check if this is of type TModel since the TModel isn't constraint to this
          if (this is not TModel model)
          {
              throw new InvalidOperationException($&quot;Instance is not of the supported type: {typeof(TModel)}. Type of {GetType()} found instead&quot;);
          }
  
          var result = _validator.Validate(model);
  
          if (result.IsValid)
          {
              return string.Empty;
          }
  
          return result.Errors.FirstOrDefault(a =&gt; a.PropertyName == propertyName)?.ErrorMessage ?? string.Empty;
      }
  
      //IDataErrorInfo implementation
      public string Error =&gt; string.Empty;
      public string this[string columnName] =&gt; ValidateAndGetErrorForProperty(columnName);
  }
  </code></pre>
  <p>And here's how I'm using it:</p>
  <pre class="lang-cs prettyprint-override"><code>public class User : ValidationBase&lt;User, UserValidator&gt;
  {
      public string Username { get; set; }
      public string Password { get; set; }
  }
  </code></pre>
  <p><strong>The problem</strong></p>
  <p>The problem I have with this solution is that you can write this invalid code:</p>
  <pre class="lang-cs prettyprint-override"><code>public class InvalidClass : ValidationBase&lt;User, UserValidator&gt;
  {
      
  }
  </code></pre>