因为我们的数组中存储的元素类型是不确定的,所以这里我们用到了泛型,其中where T : strut子句约束参数类型T必须为值类型。当然这个程序我们不使用泛型,直接定义Object类型的数组也可以。...下面重点说说C#中泛型类型参数的约束: 在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。 如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。...有关更多信息,请参见使用可以为 null 的类型(C# 编程指南)。 T:class 类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。...T: 类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。 T:U 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。...于是,我想能不能写一个简单的泛型类,其中里面实现对数值类型的加减乘除四则运算,遇到的问题是 :where子句后面的约束怎么写,我查看的数值型的类Int32等等,它们的基类是Object,如果直接定义一个泛型参数
进一步可以发现 string.Empty 实际上是一个静态只读字段,而不是一个常量。 为什么这个看起来最适合是常量的 string.Empty,竟然使用静态只读字段呢?...也就是说,string.Empty 字段并不是一个普通的字段,对它的调用会被特殊处理。但是是如何特殊处理呢?...string.Empty 字段在整个 String 类型中你都看不到初始化的代码,String 类的静态构造函数也不会执行。也就是说,String 类中的所有静态成员都不会被托管代码初始化。...String 的静态初始化过程都是由 CLR 运行时进行的,而这部分的初始化是本机代码实现的。 那本机代码又是如何初始化 String 类型的呢?...SetObjectReference( pEmptyStringHandle, StringObject::GetEmptyString(), this ); 总结:为什么 string.Empty 需要是一个静态只读字段而不是常量
Classes:面向对象特性,支持类类型 Structs:结构 Interfaces:接口 Events:事件 Properties:属性,类的成员,提供访问字段的灵活方法 Delegates:委托,一种引用类型...,通过反射可以访问特性信息 Literals:字面值(或理解为常量值),区别常量,常量是和变量相对的 C#2.0新特性 泛型及其相关,匿名方法 泛型 2.0版本的C#语言和公共语言运行时(CLR)中增加了泛型...泛型将类型参数的概念引入.NET Framework,类型参数允许类和方法将一个或多个类型的指定延迟到和护短代码声明并实例化该类或方法的时候。...当定义泛型类的实例时,必须指定这个实例所存储的实际类型: List lst = new List(); 泛型允许将一个实际的数据类型规约延迟至泛型的实例被创建时才确定...泛型主要由两个优点: 编译时可以保证类型安全。 不用做类型转换,获得一定的性能提升。
可以对支持模式的任何类型使用 fixed 语句。 可以使用其他泛型约束。 对现有功能进行了以下增强: 可以使用元组类型测试 == 和 !=。 可以在多个位置使用表达式变量。...1.5 增强的泛型约束 现在,可以将类型 System.Enum 或 System.Delegate 指定为类型参数的基类约束。...有关详细信息,请参阅有关 where 泛型约束和类型参数的约束的文章。 将这些约束添加到现有类型是不兼容的更改。 封闭式泛型类型可能不再满足这些新约束的要求。...若要使用只读引用参数调用版本,必须在调用方法前添加 in 修饰符。 有关详细信息,请参阅有关 in 参数修饰符的文章。...当一个方法组包含类型参数不满足其约束的某些泛型方法时,这些成员将从候选集中移除。 对于方法组转换,返回类型与委托的返回类型不匹配的候选方法将从集中移除。
C#访问修饰符 访问修饰符的作用 访问修饰符是用于指定成员或类型的声明可访问性的关键字。...readonly关键字(运行时常量):字段可以在声明或构造函数中初始化,常作为运行时常量使用。const关键字(编译时常量):字段只能在该字段的声明时初始化,常作为编译时常量使用过。...C# 中的 in 关键字有什么作用? in 关键字用于参数传递时,将参数按只读引用传递。使用 in 关键字可以提高性能,避免不必要的参数复制。 在 C# 中,in 关键字用于将参数标记为输入参数。...扩展方法的第一个参数不能有 in 修饰符,除非该参数是结构。 扩展方法的第一个参数,其中该参数是泛型类型(即使该类型被约束为结构。)...运算符:创建类型的新实例 修饰符:可以显式隐藏从基类继承的成员。 泛型约束:泛型约束定义,约束可使用的泛型类型。 return、continue、break的区别?
本节内容 规则 描述 CA1000:不要在泛型类型中声明静态成员 调用泛型类型的静态成员时,必须指定该类型的类型参数。 当调用不支持推理的泛型实例成员时,必须指定该成员的类型参数。...CA1003:使用泛型事件处理程序实例 某个类型包含的委托返回 void,该委托的签名包含两个参数(第一个参数是对象,第二个参数是可以分配给 EventArgs 的类型),而且包含程序集针对的是 .NET...CA1005:避免泛型类型的参数过多 泛型类型包含的类型参数越多,越难以知道并记住每个类型参数各代表什么。...CA1010:集合应实现泛型接口 若要扩大集合的用途,应实现某个泛型集合接口。 然后,可以使用该集合来填充泛型集合类型。...CA1052:应密封静态容器类型 公共或受保护类型仅包含静态成员,而且没有用 sealed (C#) 或 NotInheritable (Visual Basic) 修饰符声明该类型。
1、简介 C#是一种通用编程语言,涵盖了诸如面向对象编程,静态类型化,面向组件的编程,强类型化等各种学科。C#在ASP.NET框架中广泛用于创建网站,Web应用程序和游戏。...我们不能在静态方法中使用’This’,因为我们只能在静态方法中使用静态变量/方法。 13、常量和只读之间有什么区别? 常量变量在编译时声明和初始化。此后无法更改该值。...29、 C#.NET中的泛型是什么? 泛型用于制作可重用的代码类,以减少代码冗余,提高类型安全性和性能。使用泛型,我们可以创建集合类。...若要创建通用集合,应使用System.Collections.Generic命名空间代替System.Collections命名空间中的诸如ArrayList之类的类。泛型提倡使用参数化类型。...委托是必需的,因为它们可用于编写更多通用的类型安全函数。 34、如何在C#中将一个类继承到其他类? 冒号在C#中用作继承运算符。只需放置一个冒号,然后放置类名。
C#值类型,我们可以把他归纳成三类: 第一类: 基础数据类型(string类型除外):包括整型、浮点型、十进制型、布尔型。 ...由于值类型变量包含其实际数据,因此在默认情况下,只类型之间的参数传递不会印象变量本身; 而引用类型变量保存的是数据的引用地址,它们作为参数被传递时,参数会发生改变,从而影响应用类型变量的值。...此外,还会引起一些隐藏的bug。 所以我们在写代码时,应尽量避免装箱拆箱操作,最好使用泛型来编程。...当然泛型的好处不止于此,泛型还可以增加程序的可读性,使程序更容易被复用等等,至于泛型以后再做详细介绍....static字段和static构造函数 主要来说明执行的顺序: 1、编译器在编译的时候,先分析所需要的静态字段,如果这些静态字段所在的类有静态的构造函数,那么就会忽略字段的初始化;如果没有静态的构造函数
2、overload (重载)和 override (重写)的区别 重载是方法名相同但参数或参数类型不同,通过多次重载以适应不同的需求,是面向对象的概念。...静态字段在内存中只有一个拷贝,非静态字段在每个实例对象中都会有一个拷贝。无论方法是否为静态,在内存中就只会有一份拷贝,唯一的区别就是通过类名来访问还是通过实例来访问。...在下面的示例中,定义了一个泛型类(class SampleCollection ),并为其提供了简单的 get 和 set访问器 方法(作为分配和检索值的方法)。...interface 声明接口,它只提供一个方法归于,不能用 public 、 abstract 等修饰,没有字段没有常量以及构造函数。...相当于"",Empty 是静态只读字段,string str="" 初始对象并分配一个空字符串的内存空间,string str=null 初始化对象但是不分配内存空间。
合成的 GetHashCode 使用基类型和记录类型中声明的所有属性和字段中的 GetHashCode。 这些合成方法在整个继承层次结构中强制执行基于值的相等性。...上述位置记录示例演示了如何使用仅限 init 的资源库通过 with 表达式来设置属性。 可在编写的任何类型中声明仅限 init 的资源库。...4、模式匹配增强功能 C# 9 包括新的模式匹配改进: 类型模式要求在变量是一种类型时匹配 带圆括号的模式强制或强调模式组合的优先级 联合 and 模式要求两个模式都匹配 析取 or 模式要求任一模式匹配...最常见的用法是在字段声明中: private List _observations = new(); 当需要创建新对象作为参数传递给方法时,也可使用目标类型 new...模块初始化表达式方法: 必须是静态的 必须没有参数 必须返回 void 不能是泛型方法 不能包含在泛型类中 必须能够从包含模块访问 最后一个要点实际上意味着该方法及其包含类必须是内部的或公共的。
通过示例展示了将结构体成员设为只读后,尝试修改其字段值时,编译器不报错但修改不成功,因为只读机制会导致字段值在堆栈上拷贝。这种隐蔽的行为可能引发 BUG,如自旋锁示例中的计数错误。...文章建议在结构体或字段需要只读时,使用 readonly 关键字直接修饰,以避免潜在问题。...C# 泛型编译特性对性能的影响 https://www.cnblogs.com/tansm/p/CSharp-Generic-Performance.html 本文探讨了 C#中泛型的编译行为,特别是结构和类作为泛型参数时对性能的不同影响...结构作为值类型,存储在栈上,泛型参数为结构时编译器生成特定实现,提升性能,减少装箱拆箱。类作为引用类型,存储在堆上,泛型参数为类时编译器生成通用实现,可能导致性能下降。...性能测试显示结构类型泛型参数性能较高,类类型泛型参数性能略低。
localsinit 标志 目标类型的新表达式 静态匿名函数 目标类型的条件表达式 协变返回类型 扩展 GetEnumerator 支持 foreach 循环 Lambda 弃元参数 本地函数的属性...上述位置记录示例演示了如何使用仅限 init 的资源库通过 with 表达式来设置属性。 可在编写的任何类型中声明仅限 init 的资源库。...4、模式匹配增强功能 C# 9 包括新的模式匹配改进: 类型模式要求在变量是一种类型时匹配 带圆括号的模式强制或强调模式组合的优先级 联合 and 模式要求两个模式都匹配 析取 or 模式要求任一模式匹配...最常见的用法是在字段声明中: private List _observations = new(); 当需要创建新对象作为参数传递给方法时,也可使用目标类型 new...模块初始化表达式方法: 必须是静态的 必须没有参数 必须返回 void 不能是泛型方法 不能包含在泛型类中 必须能够从包含模块访问 最后一个要点实际上意味着该方法及其包含类必须是内部的或公共的。
可以是抽象的,并成为接口的一部分 属性也可以是抽象的,从而成为接口定义的一部分,这种属性写起来与隐士属性相似。下面这段代码,就演示了怎样在泛型接口中定义属性。...虽然与隐士属性的写法相似,但这种属性没有对应的实现物,定义该属性的接口只是要求实现本接口的类型都必须满足接口所订立的契约,也就是必须正确的提供Name及Value这两个属性: public interface...如果某个类型要在其接口中发布能够用索引来访问的内容,那么就可以创建索引器。这相当于带有参数的属性,或者说参数化的属性。...由于C#不允许给索引器起名字,因此同一个类型的索引器必须在参数列表上有所区别,否则就会产生歧义。 另外,索引器必须明确的实现出来,而不能像简单属性那样由系统默认生成。...customerOne.Name = "yilezhu"; 其实我也经常这样用,不过都是定义一些静态的全局常量。
表达式树练习实践:C#值类型、引用类型、泛型、集合、调用函数 目录 表达式树练习实践:C#值类型、引用类型、泛型、集合、调用函数 一,定义变量 二,访问变量/类型的属性字段和方法 1....访问属性 调用静态类型属性 调用实例属性/字段 2....调用函数 调用静态类型的函数 调用实例的函数 三,实例化引用类型 new 给属性赋值 创建引用类型 示例 四,实例化泛型类型于调用 五,定义集合变量、初始化、添加元素 ?...二,访问变量/类型的属性字段和方法 访问变量或类型的属性,使用 Expression.Property() 访问变量/类型的属性或字段,使用 Expression.PropertyOrField() 访问变量或类型的方法...使用上,根据实例化/不实例化,有个小区别,上面说了变量或类型。 意思是,已经定义的值类型或实例化的引用类型,是变量; 类型,就是指引用类型,不需要实例化的静态类型或者静态属性字段/方法。
委托揭秘 用委托回调多个方法(委托链) 委托定义不要太多(泛型委托) C#为委托提供的方法 委托和反射 第十八章 定制特性 使用定制特性 定义自己的特性类 特性构造器和字段/属性数据类型 检测定制特性...建议使用泛型委托捏。...为了符合“公共语言规范”(CLS)的要求,定制特性类必须直接或间接从公共抽象类System.Attribute派生。C#只允许符合CLS规范的特性。...在特性类定义了一个Type参数、Type字段或者Type属性的任何地方,都必须使用C# typeof操作符(如下例所示)。...在特性类定义了一个Object参数、Object字段或者Object属性的任何地方,都可传递一个Int32、String或其他任何常量表达式(包括null)。
. ---- 【重点面试题】32、泛型是什么 多个代码对 【不同数据类型】 执行 【相同指令】的情况 泛型:多个类型共享一组代码 泛型允许类型参数化,泛型类型是类型的模板 5种泛型:类、结构、接口...、委托、方法 类型占位符 T 来表示泛型 泛型类不是实际的类,而是类的模板 从泛型类型创建实例 声明泛型类型》通过提供【真实类型】创建构造函数类型》从构造类型创建实例 类 泛型类型参数...性能:泛型不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转换,所以性能得到提高 安全:通过知道使用泛型定义的变量的类型限制,编译器可以在一定程度上验证类型假设,所以泛型提高了程序的类型安全... Action和Func的重要区别: Action只用于没有返回值的方法,Func只用于有返回值的方法 它们泛型里的区别: Action的泛型里要和方法参数的类型相同...3、设计一个状态机类型,状态值为int类型,要求: 拥有接口,获取当前状态,切换状态 外部可以监听状态切换事件,参数为切换前状态和切换后状态(使用delete和event) 4、如何处理unity中界面资源
3.0 构建和部署 静态本地方法 从C# 8 开始,本地方法就可以是静态的了。...只读struct成员 从C# 8开始,我们可以在struct的成员上使用readonly修饰符。...其中内置的值类型有: byte int char float bool … 而构造类型(指包含至少一个类型参数的类型)不能为非托管类型。...看下面这个泛型struct: ? 在C# 7里,无论这里的T是int还是object,该类型都不可以是非托管类型,即使T是一个非托管类型。...而在C# 8里,如果构造类型的所有类型参数都是非托管类型的,那么这个构造类型就是非托管的。 所以Coords 类型在 C# 8.0 及更高版本中是非托管类型。
在C#中,readonly特性用于声明一个只读字段。一个只读字段可以在声明时或在构造函数内部进行初始化,一旦被赋予了初始值,它就不能被改变。...只读字段的值不能更改,相当于常量,但常量在编译时需要初始化,只读字段则在运行时初始化。 只读字段可以具有不同的值,取决于所用的构造函数来创建对象。...静态只读字段在运行时初始化,其初始化发生在静态构造函数中(如果存在)或者在出现此类的任何其他静态成员之前。...readonly修饰的字段GC如何处理它 垃圾收集器(GC)对 readonly 修饰的字段无特殊处理。只读性质并不影响对象的垃圾回收。 垃圾回收主要基于一个对象是否还被引用来决定是否进行回收。...readonly修饰的字段内存分配在哪里 在C#中,readonly关键字修饰的字段的内存分配位置取决于它是否被声明为静态(static)。
在高性能要求的情况下,可以考虑避免不必要的装箱和拆箱操作。 C# 中的泛型和 Nullable 类型等机制有助于减少这些操作的需求。7....:在泛型类型中,new 关键字用于创建具体类型的实例。...在泛型类型参数需要具体类型时,可以使用 new 来创建实例。...中用于创建对象、方法的重写、字段或属性的隐藏以及在泛型类型中实例化。...net中有很多内置的委托类型,如Action和Func,它们分别用于表示无返回值的方法和有返回值的方法。这些内置委托类型在泛型和非泛型形式中都可用作用:提高方法的扩展性11.
领取专属 10元无门槛券
手把手带您无忧上云