20

How can I restrict TModel to be classes only or to be implementing a specific interface?

@typeparam TModel

cannot get the syntax working.

CleanCoder
  • 2,406
  • 1
  • 10
  • 35
  • It looks like there's an open issue for this in GitHub. There's a solution that might work for you in the thread: https://github.com/dotnet/aspnetcore/issues/8433#issuecomment-545690917 – devNull Mar 17 '20 at 00:29

3 Answers3

43

From ASP.NET Core 6.0 onwards, you can use the following syntax to specify generic type constraints:

@typeparam TModel where TModel : IModel
Craig Brown
  • 1,891
  • 1
  • 24
  • 25
  • 1
    this is not working for me for some reason. .NET 7, Blazor Server, MudBlazor latest, latest. Anything I could be missing? – Victorio Berra Jun 09 '23 at 22:49
  • For me it builds but Razor editor throws errors. I also added a code-behind partial class, no help. – niw3 Jun 17 '23 at 11:41
  • If I keep the constraints in the code-behind, and keep typeparam TModel (without constraints) in the razor, it compiles without errors. – niw3 Jun 18 '23 at 09:24
15

The solution is to put the type constraint additionally in a partial code behind class. It works!

Craig Brown
  • 1,891
  • 1
  • 24
  • 25
CleanCoder
  • 2,406
  • 1
  • 10
  • 35
  • 2
    Could you please post an example? I did as you described and Blazor says that the partial has has different base classes, i.e. one (from razor) get compiled without the constraint and the second (c# code behind) with the constraint. – mihails.kuzmins Apr 14 '21 at 12:42
  • If Blazor says that the partial has a different base class, then most likely the razor file contains at least one error. That could even be a problem in a used sub view/control – CleanCoder Apr 14 '21 at 20:41
1

Indeed, the answer posted by Sven works, but there is one modification I needed to do - add <RazorLangVersion>3.0</RazorLangVersion> to my .csproj file. After that the project was compiled. So here are my complete files:

  1. Project.cs
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <RazorLangVersion>3.0</RazorLangVersion> <!-- Important -->
    <Nullable>enable</Nullable>
    <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
  </PropertyGroup>
</Project>
  1. Razor component
@typeparam TViewModel
@inherits PageBase<TViewModel>

<h3>Some text</h3>
  1. Corebehind
public abstract partial class AuthenticatedPageBase<TViewModel>
    where TViewModel : ViewModelBase
{
}

EDIT: Well, after deleting the <RazorLangVersion> tag from the csproj file it still seems to work.

mihails.kuzmins
  • 1,140
  • 1
  • 11
  • 19