title: Compiler error with generic Blazor component
body: <p>I've defined a custom <code>select</code> component in Blazor like this:</p>
  <pre class="lang-cs prettyprint-override"><code>public class BetterInputSelect&lt;TItem&gt; : InputBase&lt;TItem&gt;
  {
    [Parameter]
    public IEnumerable&lt;TItem&gt; Data { get; set; } = new List&lt;TItem&gt;();
  
    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
      builder.OpenElement(0, &quot;select&quot;);
      builder.AddMultipleAttributes(1, AdditionalAttributes);
      builder.AddAttribute(2, &quot;class&quot;, CssClass);
      builder.AddAttribute(3, &quot;value&quot;, BindConverter.FormatValue(CurrentValueAsString));
      builder.AddAttribute(4, &quot;onchange&quot;, EventCallback.Factory.CreateBinder&lt;string&gt;(
        this, value =&gt; CurrentValueAsString = value, CurrentValueAsString!, null));
  
      foreach (var item in this.Data)
      {
        builder.OpenElement(5, &quot;option&quot;);
        builder.AddAttribute(6, &quot;value&quot;, item!.ToString());
        builder.AddContent(7, this.FindDisplayName(item));
        builder.CloseElement();
      }
  
      builder.CloseElement();
    }
  
    protected override bool TryParseValueFromString(string? value, out TItem result, out string validationErrorMessage)
    {
      // Check for enums first.
      if (typeof(TItem).IsEnum &amp;&amp; BindConverter.TryConvertTo(value, CultureInfo.CurrentCulture, out TItem? parsedValue))
      {
        result = parsedValue!;
        validationErrorMessage = null!;
        return true;
      }
  
      // Other types here
      // ...
  
      result = default!;
      validationErrorMessage = $&quot;The {FieldIdentifier.FieldName} field is not valid.&quot;;
      return false;
    }
  
    private string FindDisplayName(TItem value)
    {
      return value switch
      {
        null =&gt; string.Empty,
        Enum @enum =&gt; @enum.GetDescription(),
        _ =&gt; value.ToString() ?? string.Empty
      };
    }
  }
  </code></pre>
  <p>which can then be used like this:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;BetterInputSelect Data=&quot;@Reasons&quot; @bind-Value=&quot;@Reason&quot; /&gt;
  </code></pre>
  <p>where <code>Reasons</code> and <code>Reason</code> are defined like this:</p>
  <pre class="lang-cs prettyprint-override"><code>public SomeReason Reason { get; set; }
  
  private IEnumerable&lt;SomeReason&gt;? Reasons { get; set; }
  
  ...
  
  public enum SomeReason 
  {
    ...
  }
  </code></pre>
  <p>This works great as long as the value that is bound by <code>@bind-Value</code> is not nullable. When I do:</p>
  <pre class="lang-cs prettyprint-override"><code>public SomeReason? Reason { get; set; }
  </code></pre>
  <p>I get a compile time error:</p>
  <pre class="lang-none prettyprint-override"><code>[CS0411] The type arguments for method 
  'TypeInference.CreateBetterInputSelect_0&lt;TItem&gt;(RenderTreeBuilder, int, int, IEnumerable&lt;TItem&gt;, int, TItem, int, EventCallback&lt;TItem&gt;, int, Expression&lt;Func&lt;TItem&gt;&gt;)' 
  cannot be inferred from the usage. Try specifying the type arguments explicitly.
  </code></pre>
  <p>Can I simply not bind to a nullable property, or is there a way to make the compiler happy that I've missed?</p>
  <h3>EDIT</h3>
  <p>And if I try to define the type explicitly like this:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;BetterInputSelect
    Data=&quot;@Reasons&quot; 
    @bind-Value=&quot;@Reason&quot; 
    TItem=&quot;SomeReason&quot; /&gt;
  </code></pre>
  <p>then I get the following compiler errors:</p>
  <pre class="lang-none prettyprint-override"><code>[CS1503] Argument 1: cannot convert from 'SomeReason?' to 'SomeReason'
  [CS1503] Argument 2: cannot convert from 'Microsoft.AspNetCore.Components.EventCallback&lt;SomeReason?&gt;' to 'Microsoft.AspNetCore.Components.EventCallback'
  [CS0266] Cannot implicitly convert type 'SomeReason?' to 'SomeReason'. An explicit conversion exists (are you missing a cast?)
  [CS1662] Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
  </code></pre>