-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic Blazor inheritance doesn't compile with the C# 9 Nullable setting enabled #30531
Comments
@pranavkm I don't know if you looked at the linked repro repo when you added the tags but I had needlessly used a Directory.Build.props file rather than just the |
Thanks for contacting us. |
Spent some time looking into this and I'm 100% sure its a compiler bug related to dotnet/roslyn#45960. In particular, the issue seems to be related to have multiple partial declarations of a generic class within an enabled nullability context. I tried changing the code generation for the Razor component in the following ways to see if the issue was related to anything we had control over: First, adding a generic constraint to the generated code. - public partial class TestComponent<T> : TestComponentBase<T>
+ public partial class TestComponent<T> : TestComponentBase<T> where T : class No luck here. Also tried disabling nullability around the class declaration here. - public partial class TestComponent<T> : TestComponentBase<T>
+#nullable disable
+ public partial class TestComponent<T> : TestComponentBase<T> But as mentioned above, this doesn't really do anything as long as nullability is enabled in the partial implementation in the C# file that the Razor compiler doesn't touch. With this in mind, I stepped back and decided to play with generic base classes + partial implementations + nullability in a simple console app. The following code sample compiles fine and captures some of the properties that I think exist in this problem:
public partial class TestComponent<T> : TestComponentBase<T>
{
public TestComponent()
{
TestVal = 0;
}
}
public partial class TestComponent<T> : TestComponentBase<T>
where T : class
{
public int TestVal { get; set; }
}
public class TestComponentBase<T> : Foo
where T : class
{
public int BaseVal { get; set; }
public override void Bar() {
return;
}
}
public abstract class Foo
{
public abstract void Bar();
} The issue doesn't repro in this scenario. At this point, I chased another hunch. Maybe the issue only repros with abstract classes that implement an interface? I tried the following but no dice: public partial class TestComponent<T> : TestComponentBase<T>
{
public TestComponent()
{
TestVal = 0;
}
}
public partial class TestComponent<T> : TestComponentBase<T>
where T : class
{
public int TestVal { get; set; }
}
public class TestComponentBase<T> : Foo
where T : class
{
public int BaseVal { get; set; }
public override void Bar() {
return;
}
}
public abstract class Foo : IFoo
{
public int Baz { get; set; }
public abstract void Bar();
}
public interface IFoo
{
int Baz { get; set; }
} At this point, I came across dotnet/roslyn#45960 which reminded me to put tickering with the nullability context at the forefront of my investigation. So I tried the following: #nullable disable
public partial class TestComponent<T> : TestComponentBase<T>
{
public TestComponent()
{
TestVal = 0;
}
}
#nullable enable
public partial class TestComponent<T> : TestComponentBase<T>
where T : class
{
public int TestVal { get; set; }
} And reproed the bug. OK. So what we're dealing with is exactly related to #45960. Then I realized that I missed something when I was trying:
And realized that I missed something important here. Since the issue is related to nullability mismatch, we want to enable nullability around the class declaration, not disable it, to match the nullability context in the other class declaration. Updating the code generation to produce the following: #nullable enable
public partial class TestComponent<T> : TestComponentBase<T> resolves the issue. This is just a workaround for the compiler bug referenced above but I think we can safely enable nullability around the class declaration for the meantime. I'll have to see if it is possible for us to strictly limit this to partial generic classes. Side note, I also spotted #27218 and #26971 as possible dupes of this issue in the repo. |
just to have confirmation, does this mean that actually in this scenario in net5 we can't use nullable but it will work on .net 6? |
@MithrilMan Not quite. We debugged this down to an issue in the compiler so it will depend on what version of the compiler you are using. See dotnet/roslyn#45960 for more info. |
Closing as a dupe of the linked roslyn issue. |
Describe the bug
Generic Razor components that themselves inherit from a generic base class can't have any constraints (except
struct
) if the new and great .Net5 / C# 9 Nullable setting is enabled. The compiler errors you get are very puzzling but clearly incorrect:#nullable
option todisable
makes the project compilestruct
makes the project compileNote that this only happens if the component itself has a
@typeparam
and inherits from a generic base class, while the .Net 5 / C# 9 Nullable feature is activated.To Reproduce
Here's a very minimal repro repo: https://github.com/kaleidocore/BlazorGenericsBug
Further technical details
.NET SDK (reflecting any global.json):
Version: 5.0.103
Commit: 72dec52dbd
Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.103\
Host (useful for support):
Version: 5.0.3
Commit: c636bbdc8a
.NET SDKs installed:
2.0.2 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.402 [C:\Program Files\dotnet\sdk]
2.1.520 [C:\Program Files\dotnet\sdk]
2.1.812 [C:\Program Files\dotnet\sdk]
3.1.405 [C:\Program Files\dotnet\sdk]
5.0.102 [C:\Program Files\dotnet\sdk]
5.0.103 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.24 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.24 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.24 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.12 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Visual Studio 2019, Version 16.8.5
The text was updated successfully, but these errors were encountered: