c# - C# 中的泛型类型约束
问题描述
我正在查看通用类型约束的 MSDN 文档,并找到了以下段落。
您使用默认约束来指定您的派生类覆盖没有派生类中的约束或显式接口实现的方法。它仅对覆盖基本方法或显式接口实现的方法有效:
public class D : B
{
// Without the "default" constraint, the compiler tries to override the first method in B
public override void M<T>(T? item) where T : default { }
}
我无法理解派生类在没有约束的情况下覆盖该方法的部分。这可以用一个详细的例子来解释,在“M”方法中需要为 T 传递值吗?
解决方案
如果您尝试这样做,可能会更容易理解。假设您有:
public abstract class BaseLogger
{
public void Log<T>(T? item) where T : struct
{
Console.WriteLine("I **cannot** be overriden!");
}
public virtual void Log<T>(T? item)
{
Console.WriteLine("I **can** be overriden!");
}
}
现在,您有一个子类,您要在其中覆盖唯一的虚拟方法:
public class Logger : BaseLogger
{
public override void Log<T>(T? item)
{
Console.WriteLine("I am overwriting my parent method!");
}
}
一切都好,对吧?好吧,不完全是,不:
Compilation error: 'Logger.Log<T>(T?)': cannot override inherited member 'BaseLogger.Log<T>(T?)' because it is not marked virtual, abstract, or override
Compilation error: The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable<T>'
正如文档所解释的,编译器无法解决T?
(可为空的引用类型)和T?
(的简写Nullable<T>
)之间的歧义,因此您需要一种方法来指定可以覆盖的方法。这就是新default
约束变得有用的地方:
public class Logger : BaseLogger
{
public override void Log<T>(T? item) where T: default
{
Console.WriteLine("I am overwriting my parent method!");
}
}
现在它实际上编译了。现场观看:https ://dotnetfiddle.net/vXgzWx
推荐阅读
- anaconda - 如何找到 conda-forge 包的 MD5 校验和
- curl - 如何从 developer.twitter.com 运行示例
- ruby - Ruby循环放置两条不同的消息
- r - ggplot2 如何去除重复的点?
- bash - 如何使用索引从 Jenkins 解析 .property 文件中的数据
- c# - 有没有办法在剃须刀页面的 CSHTML 条件中利用 [Authorize] 属性?
- javascript - 开玩笑的模拟功能没有按预期工作
- java - Java 11 junit jupiter assertThrows
- r - 如何在不同 geom_col 绘图的恒定垂直位置注释文本
- java - Spring Boot with read-only session for single sign on