C# 类型和成员

C# 教程 - 类型及其成员 - C# | Microsoft Learnicon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/dotnet/csharp/tour-of-csharp/types

       

目录

类和对象

类型参数

基类

结构

接口

枚举

可为 null 的类型

元组


       作为面向对象的语言,C# 支持封装、继承和多态性这些概念。 类可能会直接继承一个父类,并且可以实现任意数量的接口。 若要用方法重写父类中的虚方法,必须使用 override 关键字,以免发生意外重定义。 在 C# 中,结构就像是轻量级类,是可以实现接口但不支持继承的堆栈分配类型。 C# 提供了 record class 和 record struct 类型,这些类型的目的主要是存储数据值。

所有类型都通过构造函数(负责初始化实例的方法)进行初始化。 两个构造函数声明具有唯一的行为:

  • 无参数构造函数,该构造函数将所有字段初始化为其默认值。
  • 主构造函数,该构造函数声明该类型的实例的必需参数。

类和对象

是最基本的 C# 类型。 类是一种数据结构,可在一个单元中就将状态(字段)和操作(方法和其他函数成员)结合起来。 类为类实例(亦称为“对象”)提供了定义 。 类支持继承多形性,即派生类可以扩展和专门针对基类的机制。

新类使用类声明进行创建。 类声明以标头开头。 标头指定以下内容:

  • 类的特性和修饰符
  • 类的名称
  • 基类(从基类继承时)
  • 接口由该类实现。

标头后面是类主体,由在分隔符 { 和 } 内编写的成员声明列表组成。

以下代码展示的是简单类 Point 的声明:

public class Point
{public int X { get; }public int Y { get; }public Point(int x, int y) => (X, Y) = (x, y);
}

类实例是使用 new 运算符进行创建,此运算符为新实例分配内存,调用构造函数来初始化实例,并返回对实例的引用。 以下语句创建两个 Point 对象,并将对这些对象的引用存储在两个变量中:

var p1 = new Point(0, 0);
var p2 = new Point(10, 20);

当无法再访问对象时,对象占用的内存会被自动回收。 没有必要也无法在 C# 中显式解除分配对象。

算法的应用程序或测试可能需要创建多个 Point 对象。 以下类生成一系列随机点。 点数由主构造函数参数设置。 主构造函数参数 numPoints 在类的所有成员的范围内:

public class PointFactory(int numberOfPoints)
{public IEnumerable<Point> CreatePoints(){var generator = new Random();for (int i = 0; i < numberOfPoints; i++){yield return new Point(generator.Next(), generator.Next());}}
}

可以使用类,如下面的代码所示:

var factory = new PointFactory(10);
foreach (var point in factory.CreatePoints())
{Console.WriteLine($"({point.X}, {point.Y})");
}

类型参数

泛型类定义类型参数。 类型参数是用尖括号括起来的类型参数名称列表。 类型参数跟在类名后面。 然后,可以在类声明的主体中使用类型参数来定义类成员。 在以下示例中,Pair 的类型参数是 TFirst 和 TSecond

public class Pair<TFirst, TSecond>
{public TFirst First { get; }public TSecond Second { get; }public Pair(TFirst first, TSecond second) => (First, Second) = (first, second);
}

声明为需要使用类型参数的类类型被称为泛型类类型。 结构、接口和委托类型也可以是泛型。 使用泛型类时,必须为每个类型参数提供类型自变量:

var pair = new Pair<int, string>(1, "two");
int i = pair.First;     //TFirst int
string s = pair.Second; //TSecond string

包含类型自变量的泛型类型(如上面的 Pair<int,string>)被称为构造泛型类型

基类

类声明可以指定基类。 在类名和类型参数后面加上冒号和基类的名称。 省略基类规范与从 object 类型派生相同。 在以下示例中,Point3D 的基类是 Point 在第一个示例中,Point 的基类是 object

public class Point3D : Point
{public int Z { get; set; }public Point3D(int x, int y, int z) : base(x, y){Z = z;}
}

类继承其基类的成员。 继承意味着一个类隐式包含其基类的几乎所有成员。 类不继承实例、静态构造函数以及终结器。 派生类可以在其继承的成员中添加新成员,但无法删除继承成员的定义。 在上面的示例中,Point3D 从 Point 继承了 X 和 Y 成员,每个 Point3D 实例均包含三种属性(XY 和 Z)。

可以将类类型隐式转换成其任意基类类型。 类类型的变量可以引用相应类的实例或任意派生类的实例。 例如,类声明如上,Point 类型的变量可以引用 Point 或 Point3D

Point a = new(10, 20);
Point b = new Point3D(10, 20, 30);

结构

类定义可支持继承和多形性的类型。 它们使你能够基于派生类的层次结构创建复杂的行为。 相比之下,结构类型是较为简单的类型,其主要目的是存储数据值。 结构不能声明基类型;它们从 System.ValueType 隐式派生。 不能从 struct 类型派生其他 struct 类型。 这些类型已隐式密封。

public struct Point
{public double X { get; }public double Y { get; }public Point(double x, double y) => (X, Y) = (x, y);
}

接口

接口定义了可由类和结构实现的协定。 定义接口来声明在不同类型之间共享的功能。 例如,System.Collections.Generic.IEnumerable<T> 接口定义了一个遍历集合(如数组)中所有项的一致方法。 接口可以包含方法、属性、事件和索引器。 接口通常不提供所定义成员的实现,仅指定必须由实现接口的类或结构提供的成员。

接口可以采用“多重继承”。 在以下示例中,接口 IComboBox 同时继承自 ITextBox 和 IListBox

interface IControl
{void Paint();
}interface ITextBox : IControl
{void SetText(string text);
}interface IListBox : IControl
{void SetItems(string[] items);
}interface IComboBox : ITextBox, IListBox { }

类和结构可以实现多个接口。 在以下示例中,类 EditBox 同时实现 IControl 和 IDataBound

interface IDataBound
{void Bind(Binder b);
}public class EditBox : IControl, IDataBound
{public void Paint() { }public void Bind(Binder b) { }
}

当类或结构实现特定接口时,此类或结构的实例可以隐式转换成相应的接口类型。 例如

EditBox editBox = new();
IControl control = editBox;
IDataBound dataBound = editBox;

枚举

枚举类型定义了一组常数值。 以下 enum 声明了定义不同根蔬菜的常数:

public enum SomeRootVegetable
{HorseRadish,Radish,Turnip
}

还可以定义一个 enum 作为标志组合使用。 以下声明为四季声明了一组标志。 可以随意搭配季节组合,包括 All 值(包含所有季节):

[Flags]
public enum Seasons
{None = 0,Summer = 1,Autumn = 2,Winter = 4,Spring = 8,All = Summer | Autumn | Winter | Spring
}

以下示例显示了前面两个枚举的声明:

var turnip = SomeRootVegetable.Turnip;var spring = Seasons.Spring;
var startingOnEquinox = Seasons.Spring | Seasons.Autumn;
var theYear = Seasons.All;

可为 null 的类型

任何类型的变量都可以声明为“不可为 null”或“可为 null”_。 可为 null 的变量包含一个额外的 null 值,表示没有值。 可为 null 的值类型(结构或枚举)由 System.Nullable<T> 表示。 不可为 null 和可为 null 的引用类型都由基础引用类型表示。 这种区别由编译器和某些库读取的元数据体现。 当可为 null 的引用在没有先对照 null 检查其值的情况下取消引用时,编译器会发出警告。 当对不可为 null 的引用分配了可能为 null 的值时,编译器也会发出警告。 以下示例声明了“可为 null 的 int”,并将其初始化为 null。 然后将值设置为 5。 该示例通过“可为 null 的字符串”演示了同一概念。 有关详细信息,请参阅可为 null 的值类型和可为 null 的引用类型。

int? optionalInt = default; 
optionalInt = 5;
string? optionalText = default;
optionalText = "Hello World.";

元组

C# 支持元组,后者提供了简洁的语法来将多个数据元素分组成一个轻型数据结构。 通过声明 ( 和 ) 之间的成员的类型和名称来实例化元组,如下例所示:

(double Sum, int Count) t2 = (4.5, 3);
Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
//Output:
//Sum of 3 elements is 4.5.

元组为具有多个成员的数据结构提供了一种替代方法,且无需使用下一篇文章中介绍的构建基块。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/299142.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用uniclould开发支付宝小程序提示:Uncaught URIError: URI malformed

一般这种情况是你云数据库里的内容出现了%号,像我这种格式&#xff0c;我之前在content内容里出现了百分号&#xff0c;在小程序端那里一直报错Uncaught URIError: URI malformed 。后来把content内容里的百分号全去掉就行了。跟空格之类的没关系

PicGo+GitHub搭建免费图床

PicGoGitHub搭建免费图床 步骤 1: 安装 PicGo步骤 2:创建图床仓库步骤 3: 配置 GitHub Token步骤 4: 配置 PicGo步骤 5: 上传图片步骤 6: 访问图片 使用 GitHub 作为图床的优势在于免费、稳定且具有版本控制功能&#xff0c;特别适合个人博客、小型项目等。PicGo作为一个开源的…

电路设计(7)——窗口比较器的multism仿真

1.功能设计 构建一个窗口比较器的电路&#xff0c;在输入电压大于3.5v&#xff0c;小于0.8v时&#xff0c;蜂鸣器报警&#xff0c;输入电压在0.8v到3.5v之间时&#xff0c;不报警。 整体电路如下&#xff1a; 2.设计思路 在输入端&#xff0c;采取电阻分压的方式&#xff0c;输…

基于业务功能级别的流量控制

之前产品线上发生过若干次因为tomcat连接池被耗尽而导致宕机的故障&#xff0c;而具体根源原因则各不尽相同。有因为调用和被调用的服务申请相同的分布式锁而导致死锁的&#xff0c;有因为发送内部或外部的JMS消息发生堵塞的&#xff0c;有因为某个存在性能问题的接口被较多调用…

外汇天眼:BarnBridge解决SEC指控 SMART Yield池吸引5.09亿美元

美国证券交易委员会&#xff08;SEC&#xff09;今天宣布&#xff0c;据称是去中心化自治组织的BarnBridge DAO及其两位创始人Tyler Ward和Troy Murray将支付超过170万美元&#xff0c;以解决一项指控&#xff0c;即未注册BarnBridge发行和销售名为SMART Yield债券的结构化加密…

利用GPTs Action打造个性化智能记账助手

有 GPTs 访问权限的可以点击链接进行体验&#xff1a;https://chat.openai.com/g/g-vG7XwEfNG-zhi-neng-ji-zhang-zhu-shou 部署私人记账助手教程&#xff1a;https://github.com/Reborn14/Intelligent-Accounting-Assistant/tree/main 引言 在最近的 OpenAI 开发者大会上&…

低代码可视化工具10分钟完成应用开发

最近发现了一款容易上手、体验感不错的可视化低代码平台&#xff0c;它能够极大地简化开发过程&#xff0c;提高开发效率。 此前&#xff0c;曾和大家聊过&#xff0c;低代码编程&#xff0c;在现阶段互联网业务疯狂增长的带动之下&#xff0c;被赋予了全新的使命和义务&#x…

C语言蛇形矩阵

文章目录 每日一言题目解题思路全部代码结语 每日一言 山有榛&#xff0c;隰有苓。云谁之思&#xff1f;西方美人。 --邶风简兮 题目 解题思路 话不多说&#xff0c;直接看图 通过观察图表&#xff0c;我想到了这种方法&#xff1a; 我将数字放置的位置分为两大类&#xff…

Gitlab添加SSH后任需要输入密码问题

本文主要记录一下在Gitlab上设置过ssh秘钥后&#xff0c;任然无法进行ssh访问的问题。 配置步骤 要在GitLab中添加SSH登录&#xff0c;你需要按照以下步骤操作&#xff1a; 生成SSH密钥对 在你的本地机器上生成一个SSH密钥对。如果你已经有一个密钥对&#xff0c;你可以跳过…

TikTok与环保:短视频如何引领可持续生活方式?

在数字时代&#xff0c;社交媒体平台扮演着塑造文化和价值观的关键角色。而TikTok&#xff0c;作为一款全球短视频平台&#xff0c;不仅塑造着用户的娱乐方式&#xff0c;还在悄然地引领着可持续生活方式的潮流。本文将深入探讨TikTok与环保之间的关系&#xff0c;分析短视频如…

vue 导出 HTML 结构为 Word 文档(.docx)-支持表格、css样式、图片

在 Web 开发中&#xff0c;有时我们希望用户能够将网页上的 HTML 内容保存为 Word 文档&#xff0c;以便更方便地分享和打印。本文将介绍如何使用 html-docx-js 和 file-saver 这两个 JavaScript 库&#xff0c;实现将 HTML 结构导出为 Word 文档的功能。 工具简介 1. html-d…

多维时序 | MATLAB实CNN-Mutilhead-Attention卷积神经网络融合多头注意力机制多变量时间序列预测

多维时序 | MATLAB实CNN-Mutilhead-Attention卷积神经网络融合多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实CNN-Mutilhead-Attention卷积神经网络融合多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | …