首页 > 编程语言 >where(泛型类型约束)(C# 参考)

where(泛型类型约束)(C# 参考)

时间:2023-12-15 19:35:43浏览次数:28  
标签:C# 约束 类型 泛型 null where class

where(泛型类型约束)(C# 参考)

 

本文内容

  1. C# 语言规范
  2. 另请参阅

泛型定义中的 where 子句指定对用作泛型类型、方法、委托或本地函数中类型参数的参数类型的约束。 约束可指定接口、基类或要求泛型类型为引用、值或非托管类型。 约束声明类型参数必须具有的功能,并且约束必须位于任何声明的基类或实现的接口之后。

例如,可以声明一个泛型类 AGenericClass,以使类型参数 T 实现 IComparable<T> 接口:

C#
public class AGenericClass<T> where T : IComparable<T> { }

 备注

有关查询表达式中的 where 子句的详细信息,请参阅 where 子句

where 子句还可包括基类约束。 基类约束表明用作该泛型类型的类型参数的类型具有指定的类作为基类(或者是该基类)。 该基类约束一经使用,就必须出现在该类型参数的所有其他约束之前。 某些类型不允许作为基类约束:ObjectArray 和 ValueType。 以下示例显示现可指定为基类的类型:

C#
public class UsingEnum<T> where T : System.Enum { }

public class UsingDelegate<T> where T : System.Delegate { }

public class Multicaster<T> where T : System.MulticastDelegate { }

在可为 null 的上下文中,将强制执行基类类型的为 null 性。 如果基类不可为 null(例如 Base),则类型参数必须不可为 null。 如果基类可为 null(例如 Base?),则类型参数可以是可为 null 或不可为 null 的引用类型。 当基类不可为 null 时,如果类型参数是可为 null 的引用类型,编译器将发出警告。

where 子句可指定类型为 class 或 struct。 struct 约束不再需要指定 System.ValueType 的基类约束。 System.ValueType 类型可能不用作基类约束。 以下示例显示 class 和 struct 约束:

C#
class MyClass<T, U>
    where T : class
    where U : struct
{ }

在可为 null 的上下文中,class 约束要求类型是不可为 null 的引用类型。 若要允许可为 null 的引用类型,请使用 class? 约束,该约束允许可为 null 和不可为 null 的引用类型。

where 子句可能包含 notnull 约束。 notnull 约束将类型参数限制为不可为 null 的类型。 该类型可以是值类型,也可以是不可为 null 的引用类型。 对于在 nullable enable 上下文中编译的代码,可以使用 notnull 约束。 与其他约束不同,如果类型参数违反 notnull 约束,编译器会生成警告而不是错误。 警告仅在 nullable enable 上下文中生成。

添加可为空引用类型可能会在泛型方法的 T? 含义中产生歧义。 如果 T 是 struct,则 T? 与 System.Nullable<T> 相同。 但是,如果 T 是引用类型,则 T? 表示 null 是有效值。 出现歧义的原因是,重写方法不能包含约束。 新 default 约束解决了这种歧义。 当基类或接口声明一个方法的两个重载(一个指定 struct 约束,另一个未应用 struct 或 class 约束)时,将添加该约束:

C#
public abstract class B
{
    public void M<T>(T? item) where T : struct { }
    public abstract void M<T>(T? item);

}

使用 default 约束来指定派生类在派生类中没有约束的情况下重写方法,或指定显式接口实现。 此做法仅对重写基方法的方法或显式接口实现有效:

C#
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 { }
}

 重要

包含 notnull 约束的泛型声明可以在可为 null 的不明显上下文中使用,但编译器不会强制执行约束。

C#
#nullable enable
    class NotNullContainer<T>
        where T : notnull
    {
    }
#nullable restore

where 子句还可包括 unmanaged 约束。 unmanaged 约束将类型参数限制为名为“非托管类型”的类型。 unmanaged 约束使得在 C# 中编写低级别的互操作代码变得更容易。 此约束支持跨所有非托管类型的可重用例程。 unmanaged 约束不能与 class 或 struct 约束结合使用。 unmanaged 约束强制该类型必须为 struct

C#
class UnManagedWrapper<T>
    where T : unmanaged
{ }

where 子句也可能包括构造函数约束 new()。 该约束使得能够使用 new 运算符创建类型参数的实例。 new() 约束可以让编译器知道:提供的任何类型参数都必须具有可访问的无参数构造函数。 例如:

C#
public class MyGenericClass<T> where T : IComparable<T>, new()
{
    // The following line is not possible without new() constraint:
    T item = new T();
}

new() 约束出现在 where 子句的最后。 new() 约束不能与 struct 或 unmanaged 约束结合使用。 所有满足这些约束的类型必须具有可访问的无参数构造函数,这使得 new() 约束冗余。

对于多个类型参数,每个类型参数都使用一个 where 子句,例如:

C#
public interface IMyInterface { }

namespace CodeExample
{
    class Dictionary<TKey, TVal>
        where TKey : IComparable<TKey>
        where TVal : IMyInterface
    {
        public void Add(TKey key, TVal val) { }
    }
}

还可将约束附加到泛型方法的类型参数,如以下示例所示:

C#
public void MyMethod<T>(T t) where T : IMyInterface { }

请注意,对于委托和方法两者来说,描述类型参数约束的语法是一样的:

C#
delegate T MyDelegate<T>() where T : new();

有关泛型委托的信息,请参阅泛型委托

有关约束的语法和用法的详细信息,请参阅类型参数的约束

C# 语言规范

有关详细信息,请参阅 C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。

另请参阅

标签:C#,约束,类型,泛型,null,where,class
From: https://www.cnblogs.com/sexintercourse/p/17904058.html

相关文章

  • 解决方案 | pywintypes.com_error: (-2147221005, '无效的类字符串', None, None) --P
     1背景importpythoncomimportwin32com.clientimportmathwincad=win32com.client.Dispatch("AutoCAD.Application")#强制打开cad,该句发生报错信息doc=wincad.ActiveDocumentdoc.Utility.Prompt("Hello!Autocadfrompywin32com.\n")msp=doc.Mode......
  • SpringBoot使用Async注解实现异步线程
    1、启动类增加@EnableAsync注解2、yml增加配置spring:task:execution:pool:max-size:8core-size:8keep-alive:60queue-capacity:1000thread-name-prefix:Asnyc-task-calc-3、编写配置类AsyncTaskConfigimp......
  • 138. Copy List with Random Pointer
    题目Alinkedlistisgivensuchthateachnodecontainsanadditionalrandompointerwhichcouldpointtoanynodeinthelistornull.Returna deepcopy ofthelist.TheLinkedListisrepresentedintheinput/outputasalistof n nodes.Eachnodeisr......
  • 无涯教程-Java - int compareTo(String anotherString)函数
    此方法按字典顺序比较两个字符串。intcompareTo-语法intcompareTo(StringanotherString)这是参数的详细信息-anotherString  - 要比较的字符串。intcompareTo-返回值如果两个字符串相等则值为0,如果大于则>0,小于则<0。intcompareTo-示例publicclassTes......
  • ABC332G Not Too Many Balls 题解
    第\(i\)种球有\(a_i\)个,共\(n\)种。第\(i\)种箱子最多共装\(b_i\)个球。共\(m\)种。第\(i\)种球在第\(j\)种箱子里至多放\(ij\)个。问所有箱子放的球数最多是多少。\(1\leqn\leq500,1\leqm\leq5e5,0\leqa_i,b_i\leq1e12\)。很容易建出网络流模型。......
  • 解决方案 | AutoCAD二次开发的ProgID一览表(AutoCAD2000 ~ AutoCAD2024)
    1图片版本    2文字版本AutoCAD产品名版本号ProgIDAutoCAD2004R16AutoCAD.Application.16AutoCAD2005R16.1AutoCAD.Application.16.1AutoCAD2006R16.2AutoCAD.Application.16.2AutoCAD2007R17AutoCAD.Appl......
  • [Codeforces] CF1740D Knowledge Cards
    CF1740DKnowledgeCards题意有一个\(n\timesm\)的棋盘。现在\((1,1)\)中有一个栈,你可以按照一定的顺序进行出栈操作,每次都可以移动一个卡片到一个相邻的空白位置,但是卡片不能重合。问,能否通过若干次操作,将\((1,1)\)中全部的卡片移动到\((n,m)\)的栈中并使得这个栈按照从栈......
  • 汉源高科8路电话光端机 光纤传输8路电话 8路光纤PCM电话光端机
    8路电话光端机HY-8P是汉源高科(北京)科技有限公司采用自主知识产权的大规模集成电路,应用时分复用技术,将以太网信号和电话信号混合编码后在一对光纤上传输。实现热线电话业务传输,传输通道为光传输通道。该机采用桌面式设计,集成度高,体积小,功耗低,工作可靠,安装使用方便。主要功能与特点1:......
  • 【博主新书】《OpenCV应用开发:入门、进阶与工程化实践》
    写作初心OpenCV作为开源的计算机视觉框架已经有超过20年的发展历程,OpenCV4是OpenCV目前为止最重要的里程碑版本。OpenCV4不仅包含了传统图像处理、图像分析、特征提取等模块的各种主流算法算子,还包含了深度学习模型部署与加速支持模块,兼容支持多种硬件与操作系统。OpenCV开发的应用......
  • 汉源高科16路电话光端机 PCM电话光端机 语音对讲光端机 16门电话光端机
    16路电话光端机HY-16P是汉源高科(北京)科技有限公司采用自主知识产权的大规模集成电路,应用时分复用技术,将以太网信号和电话信号混合编码后在一对光纤上传输。实现热线电话业务传输,传输通道为光传输通道。该机采用1U机架式设计,集成度高,体积小,功耗低,工作可靠,安装使用方便。主要功能与特......