C#语言主要语言区域

目录
  • 一、数组、集合和 LINQ
    • 1、数组
  • 二、字符串内插
  • 三、模式匹配
  • 四、委托和 Lambda 表达式
  • 五、async/await
  • 六、属性

一、数组、集合和 LINQ

C# 和 .NET 提供了许多不同的集合类型。 数组包含由语言定义的语法。 泛型集合类型列在 System.Collections.Generic 命名空间中。 专用集合包括 System.Span<T> (用于访问堆栈帧上的连续内存),以及 System.Memory<T> (用于访问托管堆上的连续内存)。 所有集合(包括数组、Span<T> 和 Memory<T>)都遵循一种统一的迭代原则。 使用 System.Collections.Generic.IEnumerable<T> 接口。 这种统一的原则意味着任何集合类型都可以与 LINQ 查询或其他算法一起使用。 你可以使用 IEnumerable<T> 编写方法,这些算法适用于任何集合。

1、数组

数组是一种数据结构*_,其中包含许多通过计算索引访问的变量。 数组中的变量(亦称为数组的“元素”)均为同一种类型。 我们将这种类型称为数组的“元素类型”。

数组类型是引用类型,声明数组变量只是为引用数组实例预留空间。 实际的数组实例是在运行时使用 new 运算符动态创建而成。 new 运算指定了新数组实例的长度,然后在此实例的生存期内固定使用这个长度。 数组元素的索引介于 0 到 Length - 1 之间。 new 运算符自动将数组元素初始化为其默认值(例如,所有数值类型的默认值为 0,所有引用类型的默认值为 null)。

以下示例创建 int 元素数组,初始化此数组,然后打印此数组的内容。

int[] a = new int[10];
for (int i = 0; i < a.Length; i++)
{
    a[i] = i * i;
}
for (int i = 0; i < a.Length; i++)
{
    Console.WriteLine($"a[{i}] = {a[i]}");
}

此示例创建并在“一维数组”上进行操作。 C# 还支持多维数组。 数组类型的维数(亦称为数组类型的秩)是 1 与数组类型方括号内的逗号数量相加的结果。 以下示例分别分配一维、二维、三维数组。

int[] a1 = new int[10];
int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];

a1 数组包含 10 个元素,a2 数组包含 50 个元素 (10 × 5),a3 数组包含 100 个元素 (10 × 5 × 2)。 数组的元素类型可以是任意类型(包括数组类型)。 包含数组类型元素的数组有时称为“交错数组”,因为元素数组的长度不必全都一样。 以下示例分配由 int 数组构成的数组:

int[][] a = new int[3][];
a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];

第一行创建包含三个元素的数组,每个元素都是 int[] 类型,并且初始值均为 null。 接下来的代码行将这三个元素初始化为引用长度不同的各个数组实例。

通过 new 运算符,可以使用“数组初始值设定项”(在分隔符 { 和 } 内编写的表达式列表)指定数组元素的初始值。 以下示例分配 int[],并将其初始化为包含三个元素。

int[] a = new int[] { 1, 2, 3 };

可从 { 和 } 内的表达式数量推断出数组的长度。 数组初始化可以进一步缩短,这样就不用重新声明数组类型了。

int[] a = { 1, 2, 3 };

以上两个示例等同于以下代码:

int[] t = new int[3];
t[0] = 1;
t[1] = 2;
t[2] = 3;
int[] a = t;

foreach 语句可用于枚举任何集合的元素。 以下代码从前一个示例中枚举数组:

foreach (int item in a)
{
    Console.WriteLine(item);
}

foreach 语句使用 IEnumerable<T> 接口,因此适用于任何集合。

二、字符串内插

C# 字符串内插使你能够通过定义表达式(其结果放置在格式字符串中)来设置字符串格式。 例如,以下示例从一组天气数据显示给定日期的温度:

Console.WriteLine($"The low and high temperature on {weatherData.Date:MM-DD-YYYY}");
Console.WriteLine($"    was {weatherData.LowTemp} and {weatherData.HighTemp}.");
// Output (similar to):
// The low and high temperature on 08-11-2020
//     was 5 and 30.

内插字符串通过 $ 标记来声明。 字符串插内插计算 { 和 } 之间的表达式,然后将结果转换为 string,并将括号内的文本替换为表达式的字符串结果。 第一个表达式 ({weatherData.Date:MM-DD-YYYY}) 中的 : 指定格式字符串。 在前一个示例中,这指定日期应以“MM-DD-YYYY”格式显示。

三、模式匹配

C# 语言提供模式匹配表达式来查询对象的状态并基于该状态执行代码。 你可以检查属性和字段的类型和值,以确定要执行的操作。 switch 表达式是模式匹配的主要表达式。

四、委托和 Lambda 表达式

委托类型表示对具有特定参数列表和返回类型的方法的引用。 通过委托,可以将方法视为可分配给变量并可作为参数传递的实体。 委托还类似于其他一些语言中存在的“函数指针”概念。 与函数指针不同,委托是面向对象且类型安全的。

下面的示例声明并使用 Function 委托类型:

delegate double Function(double x);

class Multiplier
{
    double _factor;

    public Multiplier(double factor) => _factor = factor;

    public double Multiply(double x) => x * _factor;
}

class DelegateExample
{
    static double[] Apply(double[] a, Function f)
    {
        var result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }

    public static void Main()
    {
        double[] a = { 0.0, 0.5, 1.0 };
        double[] squares = Apply(a, (x) => x * x);
        double[] sines = Apply(a, Math.Sin);
        Multiplier m = new(2.0);
        double[] doubles = Apply(a, m.Multiply);
    }
}

Function 委托类型实例可以引用需要使用 double 自变量并返回 double 值的方法。 Apply 方法将给定的 Function 应用于 double[] 的元素,从而返回包含结果的 double[]。 在 Main 方法中,Apply 用于向 double[] 应用三个不同的函数。

委托可以引用静态方法(如上面示例中的 Square 或 Math.Sin)或实例方法(如上面示例中的 m.Multiply)。 引用实例方法的委托还会引用特定对象,通过委托调用实例方法时,该对象会变成调用中的 this。

还可以使用匿名函数或 Lambda 表达式创建委托,这些函数是在声明时创建的“内联方法”。 匿名函数可以查看周围方法的局部变量。

 以下示例不创建类:

double[] doubles = Apply(a, (double x) => x * 2.0);

委托不知道或不在意其所引用的方法的类。 引用的方法必须具有与委托相同的参数和返回类型。

五、async/await

C# 支持含两个关键字的异步程序:async 和 await。 将 async 修饰符添加到方法声明中,以声明这是异步方法。 await 运算符通知编译器异步等待结果完成。 控件返回给调用方,该方法返回一个管理异步工作状态的结构。 结构通常是 System.Threading.Tasks.Task<TResult>,但可以是任何支持 awaiter 模式的类型。 这些功能使你能够编写这样的代码:以其同步对应项的形式读取,但以异步方式执行。 例如,以下代码会下载 Microsoft Docs 的主页:

public async Task<int> RetrieveDocsHomePage()
{
    var client = new HttpClient();
    byte[] content = await client.GetByteArrayAsync("https://docs.microsoft.com/");

    Console.WriteLine($"{nameof(RetrieveDocsHomePage)}: Finished downloading.");
    return content.Length;
}

这一小型示例显示了异步编程的主要功能:

  • 方法声明包含 async 修饰符。
  • 方法 await 的主体是 GetByteArrayAsync 方法的返回。
  • return 语句中指定的类型与方法的 Task<T> 声明中的类型参数匹配。 (返回 Task 的方法将使用不带任何参数的 return 语句)。

六、属性

C# 程序中的类型、成员和其他实体支持使用修饰符来控制其行为的某些方面。 例如,方法的可访问性是由 publicprotectedinternal private 修饰符控制。 C# 整合了这种能力,以便可以将用户定义类型的声明性信息附加到程序实体,并在运行时检索此类信息。 程序通过定义和使用特性来指定此声明性信息。

以下示例声明了 HelpAttribute 特性,可将其附加到程序实体,以提供指向关联文档的链接。

public class HelpAttribute : Attribute
{
    string _url;
    string _topic;

    public HelpAttribute(string url) => _url = url;

    public string Url => _url;

    public string Topic
    {
        get => _topic;
        set => _topic = value;
    }
}

所有特性类都派生自 .NET 库提供的 Attribute 基类。 特性的应用方式为,在相关声明前的方括号内指定特性的名称以及任意自变量。 如果特性的名称以 Attribute 结尾,那么可以在引用特性时省略这部分名称。 例如,可按如下方法使用 HelpAttribute

[Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/features")]
public class Widget
{
    [Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/features",
    Topic = "Display")]
    public void Display(string text) { }
}

此示例将 HelpAttribute 附加到 Widget 类。 还向此类中的 Display 方法附加了另一个 HelpAttribute。 特性类的公共构造函数控制了将特性附加到程序实体时必须提供的信息。 可以通过引用特性类的公共读写属性(如上面示例对 Topic 属性的引用),提供其他信息。

可以在运行时使用反射来读取和操纵特性定义的元数据。 如果使用这种方法请求获取特定特性,便会调用特性类的构造函数(在程序源中提供信息)。 返回生成的特性实例。 如果是通过属性提供其他信息,那么在特性实例返回前,这些属性会设置为给定值。

下面的代码示例展示了如何获取与 Widget 类及其 Display 方法相关联的 HelpAttribute 实例。

Type widgetType = typeof(Widget);

object[] widgetClassAttributes = widgetType.GetCustomAttributes(typeof(HelpAttribute), false);

if (widgetClassAttributes.Length > 0)
{
    HelpAttribute attr = (HelpAttribute)widgetClassAttributes[0];
    Console.WriteLine($"Widget class help URL : {attr.Url} - Related topic : {attr.Topic}");
}

System.Reflection.MethodInfo displayMethod = widgetType.GetMethod(nameof(Widget.Display));

object[] displayMethodAttributes = displayMethod.GetCustomAttributes(typeof(HelpAttribute), false);

if (displayMethodAttributes.Length > 0)
{
    HelpAttribute attr = (HelpAttribute)displayMethodAttributes[0];
    Console.WriteLine($"Display method help URL : {attr.Url} - Related topic : {attr.Topic}");
}

到此这篇关于C#语言主要语言区域的文章就介绍到这了,更多相关主要语言区域内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c#语言入门类型和成员

    目录 一.类和对象 1.类型参数 2.基类 二.结构 三.接口 四.枚举 五.可为 null 的类型 六.元组 前言: 作为面向对象的语言,C# 支持封装.继承和多态性这些概念. 类可能会直接继承一个父类,并且可以实现任意数量的接口. 若要用方法重写父类中的虚方法,必须使用 override 关键字,以免发生意外重定义. 在 C# 中,结构就像是轻量级类,是可以实现接口但不支持继承的堆栈分配类型. C# 提供了 record class 和 record struct 类型,这些类型的目的主要是

  • C# 语言入门基础介绍

    目录 一..NET 体系结构 二.Hello world 三.类型和变量 四.程序结构 前言: C#(读作"See Sharp")是一种新式编程语言,不仅面向对象,还类型安全. 开发人员利用 C# 能够生成在 .NET 中运行的多种安全可靠的应用程序. C# 源于 C 语言系列,C.C++.Java 和 JavaScript 程序员很快就可以上手使用. 本教程概述了 C# 8 及更高版本中该语言的主要组件. C# 是面向对象的.面向组件的编程语言. C# 提供了语言构造来直接支持这些概

  • c#语言程序构建基块

    目录 1.成员 2.辅助功能 3.字段 4.方法 4.1参数 4.2方法主体和局部变量 4.3静态和实例方法 4.4虚方法.重写方法和抽象方法 4.5方法重载 5.其他函数成员 5.1构造函数 5.2"属性" 5.3索引器 5.4事件 5.5运算符 5.6终结器 6.表达式 7.语句 上文c#语言入门类型和成员中介绍的类型是使用以下构建基块生成的:成员*_.表达式和语句_*. 1.成员 class 的成员要么是静态成员,要么是实例成员. 静态成员属于类,而实例成员则属于对象(类实例).

  • C#语言主要语言区域

    目录 一.数组.集合和 LINQ 1.数组 二.字符串内插 三.模式匹配 四.委托和 Lambda 表达式 五.async/await 六.属性 一.数组.集合和 LINQ C# 和 .NET 提供了许多不同的集合类型. 数组包含由语言定义的语法. 泛型集合类型列在 System.Collections.Generic 命名空间中. 专用集合包括 System.Span<T> (用于访问堆栈帧上的连续内存),以及 System.Memory<T> (用于访问托管堆上的连续内存).

  • Go语言实现AOI区域视野管理流程详解

    目录 一.定义管理器接口 二.定义区域tower 三.AOI的具体方法实现 1.进入实现 2.离开区域 3.移动 4.同步 优化的思路一般是: 第一个是尽量降低向客户端同步对象的数量,第二个是尽量降低单个对象向客户端同步的数据. "九宫格"是最常见的视野管理算法了.它的优点在于原理和实现都非常简单. // AOI 管理器 type AOIManager interface { GetWidth() int GetHeight() int OnEnter(obj scene.GameOb

  • 为什么要学习C语言 C语言优势分析

    不止一个学生问到我:"老师,为什么我们的应用程序设计要学C语言而不是别的?C语言不是已经过时了吗?如果现在要写一个Windows程序,用VB或Dephi开发多快呀,用C行吗?退一万步,为什么选择C而不是C++呢?" 这个问题三言两语还真说不全.简单来说,C语言是计算机程序语言的基础,是实用的程序设计工具,学好C语言对你今后学习JAVA.C++.VB等可以打下良好的基础,因为这些语言大部分都是由C语言扩充或衍生而来的.C可以用于开发比较底层的东西,比如驱动.通信协议之类,在Unix和Li

  • 详解易语言导入语言包方法

    可能有不少软件作者因为语言包的问题而纠结,因为易语言没自带导入语言包的命令,所以只能用最普通的方式来导入语言包 1.新建一个"易语言"窗口程序 2.然后在桌面创建两个语言配置文件 你可以选择自己喜爱的语言 我在这里创建了英语和中文两个语言配置文件 3.组件有一个按钮 六个标签 两个单选框 标签内容对应语言配置文件 你可以根据自己喜爱更改 我只是举个例子 4.具体代码如下: .版本 2 .支持库 shell .程序集 窗口程序集_启动窗口 .程序集变量 语言, 文本型 .子程序 导入语言

  • CodeIgniter多语言实现方法详解

    本文实例分析了CodeIgniter多语言实现方法.分享给大家供大家参考,具体如下: CI应用目录下有一个language语言包目录,用来配置多种不同的语言.语言的配置位于config文件中,配置格式如下: 复制代码 代码如下: $config['language'] = 'english'; 定义语言文件 language下有个空的english目录,即上面定义的系统默认语言目录,系统会从该目录加载语言包文件.如果要定义不同的语言包,如zh_cn,则创建zh_cn目录并配置相应语言包文件即可.

  • Thinkphp搭建包括JS多语言的多语言项目实现方法

    本文实例讲述了Thinkphp搭建包括JS多语言的多语言项目实现方法.分享给大家供大家参考.具体实现方法如下: 一.问题: 项目需要开发英文版,于是需要搭建多语言项目. 项目使用Thinkphp框架,隐约记得Thinkphp有多语言设置,翻看了帮助手册,果然有,这就边实验边开始: 二.实现方法: Thinkphp采用app_begain来检测和切换语言包,语言包和项目相关,构架等都比较简单,具体的这里:http://www.thinkphp.cn/info/188.html 搭建好了,就可以使用

  • 学编程选什么语言好?是PHP、Python还是Ruby?

    简单地一句话总结: 1.假如你想帮他尽快找个活儿,赚到钱,推荐PHP. 2.假如你想让他成为一个高效工程师,推荐 Python. 3.假如你想让他爱上他的工作,推荐 Ruby. 语言的选择: 编程语言非常重要,不要认为他们都图灵等价,用起来都一样.实际上,好的语言,带给你的东西是超乎想像的. 下面是一些看法: 1.程序员的时间远比机器的时间宝贵:选择开发效率最高的语言吧,不要过于在乎运行性能,如果你开发不出东西,那么跑得多快也没用. 2.优雅的抽象胜于简单的堆砌: 这意味着你的代码是最简洁而又充

  • Java程序与C语言的区别浅析

    Java和C语言虽有相同性,但两者也有一定的不同.Java程序是面向对象的一种简单.分布式 .解释.健壮.安全.结构中立.可移植.高效能.多线程.动态的语言它是面向对象而C语言是面向过程的,这是最大的不同,对于学过C语言的我们来说,Java可以说是比较简单的编程语言. 在Java语言中,所有的变量必须要首先声明,然后才能使用. Java中可以有若干类但有且只有一个public,一个类中至少含有一个main方法,否则程序不能运行.而一个C语言由若干函数构成,其中必须且只有一个main的主函数,程序

  • JavaScript入门之语言基础第1/2页

    JavaScript 语言正越来越受欢迎,可以说是是互联网上最突出的语言之一.你可以跨平台和浏览器使用它,其并不排斥后端语言.现在有许多不同的开发库--有些非常棒-- 这些库对开发很有帮助,比如说加快了开发的时间等等.问题是,有时候这些库与原始语言之间很是有一些距离,这使得刚入门的开发者缺乏一种对语言的基础了解. 本文通过全面列举基础的JavaScript概念这一方式来阐述该语言的基本原理,以此来为初学者提供一个对语言的基本了解,随处可见的代码例子则是用来说明所有的这些概念是如何在语言中体现出来

  • 在Django框架中设置语言偏好的教程

    一旦你准备好了翻译,如果希望在Django中使用,那么只需要激活这些翻译即可. 在这些功能背后,Django拥有一个灵活的模型来确定在安装和使用应用程序的过程中选择使用的语言. 要设定一个安装阶段的语种偏好,请设定LANGUAGE_CODE.如果其他翻译器没有找到一个译文,Django将使用这个语种作为缺省的翻译最终尝试. 如果你只是想要用本地语言来运行Django,并且该语言的语言文件存在,只需要简单地设置 LANGUAGE_CODE 即可. 如果要让每一个使用者各自指定语言偏好,就需要使用

随机推荐