2017-08-01 3 views
-1

Avec cette définitionC# 6 génériques ne fournissent qu'un seul des types explicitement

public static HtmlTable<TRowModel> DisplayTable<TModel, TRows, TRowModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TRows>> expression, TRowModel rowModel = default(TRowModel)) where TRows : IEnumerable<TRowModel> 
    { 

     Func<TModel, TRows> deleg = expression.Compile(); 
     TRows result = deleg(helper.ViewData.Model); 

     return new HtmlTable<TRowModel>(helper.ViewData.Model, result); 
    } 

je peux appeler ma méthode extensions comme ce

@(Html.DisplayTable(m => m.ListTest, new RowViewModel()).Render()) 

Je voudrais être en mesure de préciser explicitement que la TRowModel tapez donc je peux appeler mon extension comme si

@(Html.DisplayTable<RowViewModel>(m => m.ListTest).Render()) 

ou, mieux encore, comme

@(Html.DisplayTable(m => m.ListTest).Render()) 

RowViewModel serait du fait inférer que je restreint mon paramètre lambda avec where TRows : IEnumerable<TRowModel>

Est-ce possible en C# 6? Si non, quelles sont mes alternatives pour éviter de passer un objet vide juste pour ne pas avoir à spécifier explicitement chaque type dans le diamant?

+1

Si tous les types génériques sont inférescibles à partir des paramètres, vous pouvez les ignorer tous. Si tous les types ne sont pas inférissables, alors vous devez tous les spécifier (sauf pour le paramètre 'this'). Pour plus d'informations, voir cette réponse du grand Jon Skeet: https://stackoverflow.com/a/6878596/1220550 –

+1

Vous pouvez en effet déduire l'utilisation de génériques, mais si vous commencez à les spécifier, vous devez aller à la fin. C'est soit DoSomething ("foo", 1); 'ou' DoSomething ("bar", 2); ' Modifier: @PeterB était plus rapide que moi. : (...;) – Atlasmaybe

+0

Merci à vous deux pour. Je comprends maintenant un peu plus sur les génériques. Et je suis très mécontent de cela ... cela signifie que je vais devoir garder cela laid, 'nouveau RowViewModel()' qui, pour une bibliothèque, n'est pas très convivial ni beau. Je suppose qu'il n'y a aucun moyen pour moi d'utiliser le fait que 'TRows' est forcé d'être un' IEnumerable' pour utiliser le 'TRowModel' de' where TRows: IEnumerable '? Si cela est possible, je n'irais pas à l'encontre de la règle que vous venez de me donner "soit tout soit aucun" ... – Wndrr

Répondre

0

Note: ce poste est seulement destiné à me laisser baliser cette question comme une réponse

Réponse: En C#, lorsque les médicaments génériques sont impliqués, ils doivent TOUS être spécifié explicitement, sauf si elles peuvent ALL être appel d'utilisation inférée. Le paramètre this est la seule exception à cette règle.

Merci à @Peter B et @Atlasmaybe pour vos réponses.