C#中如何重写带有可空注解的泛型方法?
C# 泛型方法可空注解重写报错解决方案
报错原因
两个报错都是C#可空上下文下无约束泛型参数的T?语义歧义导致的:
- 无任何约束的前提下,
T?默认被编译器解析为Nullable<T>(即可空值类型),要求T必须是非空值类型,没有添加对应约束就触发了第二条报错。 - 基类和派生类中
T?的语义解析不一致,导致编译器认为重写方法的返回类型和基类不匹配,触发第一条报错。
修复方案
方案1:添加notnull泛型约束(推荐,适配引用/值两类可空场景)
给泛型方法添加where T : notnull约束后,T?会被统一解析为「T类型对应的可空版本」,不管T是引用类型还是值类型都符合语义:
#nullable enable public class Stuff<T> {} public abstract class Base { public virtual Stuff<T?>? MakeStuff<T>() where T : notnull => null; public Stuff<T?>? MakeStuff2<T>() where T : notnull => null; } public abstract class Derived : Base { public override Stuff<T?>? MakeStuff<T>() where T : notnull => base.MakeStuff<T>(); }
方案2:限定T为引用类型
如果业务场景中T只会是引用类型,直接添加where T : class约束即可:
#nullable enable public class Stuff<T> {} public abstract class Base { public virtual Stuff<T?>? MakeStuff<T>() where T : class => null; public Stuff<T?>? MakeStuff2<T>() where T : class => null; } public abstract class Derived : Base { public override Stuff<T?>? MakeStuff<T>() where T : class => base.MakeStuff<T>(); }
方案3:保留无约束泛型
如果需要支持任意类型的T(包括可空值/引用类型),可以用[MaybeNull]特性替代T?注解来表达可空语义:
#nullable enable using System.Diagnostics.CodeAnalysis; public class Stuff<T> {} public abstract class Base { public virtual Stuff<[MaybeNull] T>? MakeStuff<T>() => null; public Stuff<[MaybeNull] T>? MakeStuff2<T>() => null; } public abstract class Derived : Base { public override Stuff<[MaybeNull] T>? MakeStuff<T>() => base.MakeStuff<T>(); }
内容的提问来源于stack exchange,提问作者Jeremy Richards
相关产品推荐
相关产品推荐

