C#语言发展历程(1-7)

news2025/4/22 11:31:06

一、类型发展

C#1中是没有泛型的 在C#2中在逐渐推出泛型。C#2还引入了可空类型。

示例:C#泛型(详解)-CSDN博客

1 C#3:引入了匿名类型、和隐式的局部变量(var)

匿名类型:我们主要是使用在LINQ查询语句。就算没有LINQ查询语句我们在一种类型只在一个方法中,我们创建数据类型供单一方法的使用,的这种方式也不可取。不过需要注意匿名类型的作用域只在声明的局部作用域中能使用。

示例:高级C#技术(二)-CSDN博客

2 C#7中可以采用Readonly Struct 自定义结构

举个例子:

public readonly struct Point
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}
Point p1 = new Point(2, 3);
Console.WriteLine($"p1: ({p1.X}, {p1.Y})");

// 尝试修改结构的属性值,将会引发编译错误
// p1.X = 5;
// p1.Y = 10;

Point p2 = new Point(5, 10);
Console.WriteLine($"p2: ({p2.X}, {p2.Y})");

// 结构的属性值无法修改,因此下面的赋值操作是创建了一个新的Point实例
Point p3 = p2;
Console.WriteLine($"p3: ({p3.X}, {p3.Y})");

示例解释:
         上述代码中,我们创建了一个Point对象,打印了它的坐标,并尝试修改它的属性值。由于Point是不可变的结构,所以修改属性值的操作会导致编译错误。然后,我们创建了另一个Point对象p2,并将其赋值给p3。由于结构是不可变的,所以赋值操作实际上是创建了一个新的Point实例。 

 3 C#7中引入了元组:

        元组可以替代我们前面提到的匿名类型。其中不同的是元组可以用于方法的返回类型,和参数。建议放在内部的API中不对外暴露。因为元组只是对简单的值组合进行一个赋值。并没有对其封装。

举个例子:

你可以使用如下的语法来创建一个元组:

var myTuple = (value1, value2, value3);

你还可以给元组的成员命名,以增加代码的清晰度:

var myNamedTuple = (Name: "John", Age: 30, City: "New York");

也可创建匿名类型 任何类型都可以创建

怎么使用?

 var myTuple = (45, 88, 99);
 Console.WriteLine(myTuple.Item1);//代表第一个元素   结果 45

如果您给元组的成员命名了 那么就可以使用名称来输出

 var myNamedTuple = (Name: "John", Age: new { maximum = "100", minimum = "10" }, City: "New York");
 Console.WriteLine(myNamedTuple.Name);

当需要访问元组的成员时,你可以使用点符号或者解构语法来拆包:

var myNamedTuple = (Name: "John", Age: new { maximum = "100", minimum = "10" }, City: "New York");
Console.WriteLine(myNamedTuple.Name);
var (name, age, city) = myNamedTuple;
Console.WriteLine(name);
Console.WriteLine(age.maximum);  // 访问嵌套匿名类型的属性
Console.WriteLine(city);

下面是一个示例,展示了如何在方法的返回类型和参数中使用元组:

public static (int, string) GetPerson()
{
    int age = 25;
    string name = "John Doe";
    return (age, name);
}

public static void PrintPerson((int, string) person)
{
    Console.WriteLine("Name: " + person.Item2);
    Console.WriteLine("Age: " + person.Item1);
}

// 使用示例
var person = GetPerson();
PrintPerson(person);

C#8中引入了可空引用类型:C#8假设没有使用任何显示声明的返回值、参数、属性、全局或局部变量都是默认为为空类型的。

二、代码更简洁

1 C#1中,需要先写一个委托可以指向方法,然后再写一大段代码来创建委托。

举个例子:

class Myeven
{
    public delegate void MyAction(object sender, ElapsedEventArgs e);
    public event MyAction myeven;
    Timer Timer;
    public Myeven()
    {
        Timer ??= new Timer();
        Timer.Elapsed +=  new  ElapsedEventHandler(DLonti);
    }

    private void DLonti(object sender, ElapsedEventArgs e)
    {
       
    }
}

2 C#2引入方法组转换和匿名方法后就可以采用以下形式,匿名方法没有参数列表则可以忽略

class Myeven
{
    public delegate void MyAction(object sender, ElapsedEventArgs e);
    public event MyAction myeven;
    Timer Timer;
    public Myeven()
    {
        Timer ??= new Timer();
        Timer.Elapsed += delegate (object L, ElapsedEventArgs elapsedEventArgs)
        {
            //方法体
        };
    }
}

提示:在匿名方法当中您必须显示指定参数类型。 

3 C#3推出Lambda表达式几乎具备了匿名函数的所有优点而且它的语法更简洁

class Myeven
{
    public delegate void MyAction(object sender, ElapsedEventArgs e);
    public event MyAction myeven;
    Timer Timer;
    public Myeven()
    {
        Timer ??= new Timer();
        Timer.Elapsed += (obj, e) => { //隐式声明参数列表
        
            //方法体
        };
        //Timer.Elapsed += (object obj, ElapsedEventArgs e) => {//显示声明参数列表

        //    //方法体
        //};
    }
}

4 C#3引入了对象初始化和集合初始化。

示例:高级C#技术(一)-CSDN博客

5 C#3推出了自动属性

举个例子:

class Myeven
{
	//自动属性 C#3中引人的
    public int MyProperty { get; set; }

	private int myVar;
    //传统属性
    public int MyProperty2
	{
		get { return myVar; }
		set { myVar = value; }
	}

}

6 C#6引入了表达式主体成员

在上面的示例中,我们可以将 MyProperty2 属性改写为使用表达式主体成员的形式,

如下所示:

public int MyProperty2
{
    get => myVar;
    set => myVar = value;
}

示例解释:

        我们使用 => 箭头运算符来定义属性的读取和写入逻辑。对于 get 访问器,我们直接返回 myVar 字段的值;对于 set 访问器,我们将属性的值赋给 myVar 字段。 

三、字符串处理

1 C#4引用了动态类型

示例:高级C#技术(二)-CSDN博客

2 C#5引入了调用方法信息特性

举个例子:

using System;
using System.Runtime.CompilerServices;

public class Program
{
    public static void Main(string[] args)
    {
        LogMessage("Hello, world!");
    }

    public static void LogMessage(string message,
        [CallerFilePath] string filePath = "",
        [CallerLineNumber] int lineNumber = 0,
        [CallerMemberName] string memberName = "")
    {
        Console.WriteLine($"Message: {message}");
        Console.WriteLine($"File Path: {filePath}");
        Console.WriteLine($"Line Number: {lineNumber}");
        Console.WriteLine($"Member Name: {memberName}");
    }
}

示例解释:

        在上面的示例中,我们定义了一个名为 LogMessage 的方法,并将其标记为使用了 "调用方信息特性"。在 LogMessage 方法的参数中,我们使用了 CallerFilePathCallerLineNumberCallerMemberName 属性。这些属性会自动获取调用方的文件路径、行号和成员名称。

Main 方法中调用 LogMessage 方法时,会将参数传递给 LogMessage。当执行到 LogMessage 方法时,你将看到输出的结果如下:

 输出结果:

3 C#6引入了nameof 运算符用于获取变量类型方法和成员的名字

举个例子:

class Myeven:INotifyPropertyChanged
{
	private int myVar;
	public int MyProperty
	{
		get { return myVar; }
		set { myVar = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(myVar))); }//nameof(myVar)替代原来的 "myVar"
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

4 C#6引入了内插字符串字面量

举个例子:

class Myeven
{
    private int name;
    public int Name
    {
        get { return name; }
        set { name = value; }
    }
    public Myeven()
    {
        Console.WriteLine("姓名"+Name);
        Console.WriteLine($"姓名{Name}");
    }
}

 只是部分内容分享其实还有很多我没有提及到

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯C/C++程序设计——日期统计

问题描述 小蓝现在有一个长度为 100100 的数组,数组中的每个元素的值都在 00 到 99 的范围之内。数组中的元素从左至右如下所示: 现在他想要从这个数组中寻找一些满足以下条件的子序列: 子序列的长度为 88;这个子序列可以按照下…

【数据结构】栈和队列(栈的基本操作和基础知识)

🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343🔥 系列专栏:《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm1001.2014.3001.5482 目录 前言 栈 栈的概念和结构 栈的实现 ​…

Python+OpenGL绘制3D模型(九)完善插件功能: 矩阵,材质,法线

系列文章 一、逆向工程 Sketchup 逆向工程(一)破解.skp文件数据结构 Sketchup 逆向工程(二)分析三维模型数据结构 Sketchup 逆向工程(三)软件逆向工程从何处入手 Sketchup 逆向工程(四&#xf…

结构体:搜索链表

#include<iostream> #include<iomanip> using namespace std; struct Student //创建结构体Student {int number; //学号char name[20]; //姓名float Chinese, Math, English; //成绩语数英Student* next; //下一个节点 }; Student* CreateList() //创建链表 {Stud…

Pytorch的讲解及实战·MNIST数据集手写数字识别

目录 一、前言与pytorch的下载 1、前言 2、下载pytorch ①创建虚拟环境 ②下载pytorch&#xff08;cpu版&#xff09; ③测试pytorch是否下载成功 ④使用jupyter notebook 但是使用不了torch的解决方法 二、pytorch的使用 1、Tensor的数据类型 ①torch.FloatTensor …

【网络安全 | Misc】a_good_idea

正文 使用winhex看到有zip压缩包&#xff1a; 改后缀&#xff1a; 得到两张图&#xff0c;txt中写道&#xff1a;寻找像素的秘密 使用stegsolve将合并两张图并进行像素相减&#xff1a; 再将该图进行转换色道&#xff1a; 扫描二维码得到flag&#xff1a;

计算机网络【HTTP 灵魂拷问?】

1. HTTP 报文结构是怎样的&#xff1f; 对于 TCP 而言&#xff0c;在传输的时候分为两个部分:TCP头和数据部分。 而 HTTP 类似&#xff0c;也是header body的结构&#xff0c;具体而言: 起始行 头部 空行 实体由于 http 请求报文和响应报文是有一定区别&#xff0c;因此…

【基础】【Python网络爬虫】【4.requests入门】(附大量案例代码)(建议收藏)

Python网络爬虫基础 requests 入门1. 请求方法&#xff08;Method&#xff09;2. GET与POST方法3. 简单爬虫4. url地址构成url的概念url的组成部分案例 - 添加请求头发送 5. 查看请求体6.查看响应体案例 - 某厨房首页数据爬取&#xff08;UA检测&#xff09; 7. 设置响应体编码…

uni-app uni-app内置组件

锋哥原创的uni-app视频教程&#xff1a; 2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中...共计23条视频&#xff0c;包括&#xff1a;第1讲 uni…

Vue2【插槽】

目录 1&#xff1a;插槽-默认插槽&#xff1a; 2&#xff1a;插槽-具名插槽 &#xff1a; 3&#xff1a;插槽-作用域插槽&#xff1a; 总结&#xff1a;2023再见&#xff0c;2024再见&#xff01;&#xff01;&#xff01; 1&#xff1a;插槽-默认插槽&#xff1a; 作用&a…

【neo4j】简单使用

【neo4j】简单使用 创建节点 需要建立一个symmap中医数据集的节点&#xff0c;从csv中读取数据 下面是herb的数据 将该文件放在import中 将xlsx文件转换为csv LOAD CSV WITH HEADERS FROM "file:///herb.csv" AS line CREATE (:herb {name:line.Chinese_name,p…

线上发布稳定性方案介绍

目录 一、方案说明 二、线上发布问题描述 2.1 无损上下线背景说明 2.1.1 服务⽆法及时下线 2.1.2 初始化慢 2.1.3 注册太早 2.1.4 发布态与运⾏态未对⻬ 三、问题解决方案 3.1 无损下线方案 3.1.1 什么是无损下线 3.1.2 传统解决方式 3.1.3 云原生场景解决方案 3.1…

在macOS中搭建.NET MAUI开发环境

文章目录 准备安装扩展安装 .NET安装工作负载安装 Xcode 命令行工具调试安卓应用安装 JDK安装 Android SDK 安装 Android 模拟器安装模拟器安装镜像创建虚拟机 同意许可条款创建 MAUI 项目调试 MAUI 应用切换调试目标 参考资料 准备 一台 macOS Monterey 以上的电脑安装 XCode…

FileZilla的安装与使用

文章目录 一、FileZilla简介1.1 FileZilla概述1.2 FileZilla 的优点1.3 FileZilla 的应用场景 二、搭建FileZilla服务器2.1 下载2.2 安装服务端2.3 新建组2.4 新建用户2.5 新建目录2.6 权限分配2.7 安装客户端2.8 FilaZilla远程连接 三、主被动模式 一、FileZilla简介 1.1 Fil…

【SpringCloud】从实际业务问题出发去分析Eureka-Server端源码

文章目录 前言1.EnableEurekaServer2.初始化缓存3.jersey应用程序构建3.1注册jeseryFilter3.2构建JerseyApplication 4.处理注册请求5.registry&#xff08;&#xff09; 前言 前段时间遇到了一个业务问题就是k8s滚动发布Eureka微服务的过程中接口会有很多告警&#xff0c;当时…

STM32入门教程-2023版【3-2】使用库函数点亮GPIO灯

关注 点赞 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 二、正式点亮一个LED灯 &#xff08;3&#xff09;使用库函数点亮GPIO灯 RCC初始化 首先用的是&…

【Java | 多线程案例】定时器的实现

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【Java系列专栏】【JaveEE学习专栏】 本专栏旨在分享学习JavaEE的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 这里写…

“推荐大战:抖音vs.快手”——背后的秘密全揭晓!

大家好&#xff0c;我是小米&#xff0c;一个热衷于技术分享的小伙伴。最近在面试的时候遇到了一个非常有趣的问题&#xff0c;也是很多人关心的话题——字节跳动产品面试题&#xff1a;说一下抖音和快手的推荐策略有什么不同&#xff1f;今天&#xff0c;就让我们一起来揭开这…

前端vue uni-app使用Vue和ECharts构建交互式树形结构图

题目&#xff1a;使用Vue和ECharts构建交互式树形结构图 摘要&#xff1a;本文介绍了如何使用Vue.js和ECharts构建一个交互式的树形结构图。通过整合ECharts的强大可视化功能&#xff0c;我们创建了一个可拖拽移动、点击展开和收缩的树形结构图&#xff0c;并实现了无限添加子…

《Spring Cloud学习笔记:微服务保护Sentinel + JMeter快速入门》

Review 解决了服务拆分之后的服务治理问题&#xff1a;Nacos解决了服务治理问题OpenFeign解决了服务之间的远程调用问题网关与前端进行交互&#xff0c;基于网关的过滤器解决了登录校验的问题 流量控制&#xff1a;避免因为突发流量而导致的服务宕机。 隔离和降级&#xff1a…