【问题标题】:Generic type constraint in C#C# 中的泛型类型约束
【发布时间】:2021-10-01 21:41:55
【问题描述】:

我正在查看通用类型约束的 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 传递值?

【问题讨论】:

标签: c# .net


【解决方案1】:

如果您尝试这样做,可能会更容易理解。假设您有:

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&lt;T&gt; 的简写)之间的歧义,因此您需要一种方法来指定可以覆盖的方法.这就是新的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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    相关资源
    最近更新 更多