高级C#技术(二)

前言

本章为高级C#技术的第二节也是最后一节。前一节在下面这个链接

高级C#技术icon-default.png?t=N7T8https://blog.csdn.net/qq_71897293/article/details/134930989?spm=1001.2014.3001.5501

匿名类型

匿名类型如其名,匿名的没有指定变量的具体类型。

举个例子:

1 创建一个类

    public class Student{public int Age { get; set; }public int Weight { get; set; }public string Name { get; set; }}

2 创建一个Student的实例化,并且将这个类的所有成员进行了一个初始化

 Student student = new Student{Age = 10,Weight = 100,Name = "",};

示例解释:当前代码的写法是上一节提到的对象初始化器。

创建一个匿名类型:

var Variable = new
{Age = 10,Weight = 100,Name = "",
};

示例解释:

        1 使用了var 关键字 ,因为匿名函数没有可以使用的标识符(类型)
        2 new 关键字后没有举明具体类型,等于是告诉编译器我们需要使用匿名类型
        3 在系统的智能提示中,我们鼠标放在变量类型上都会显示相应的变量类型。 而匿名类型则是用a来表示。       

图例:

注意:当前匿名类型不是创建了Student的实例,而是一个自定义的匿名类型两者没有关系。

使用匿名类型:

var s = Variable.Age;//可以通过创建的匿名类型,拿到匿名类型的成员,但这些数据是只读的

注意:可以通过创建的匿名类型,拿到匿名类型的成员,但这些数据是只读的 

扩展(此处引入书上源码)

var animals = new[]
{new { Name = "Benjamin", Age = 42, Weight = 185 },new { Name = "Benjamin", Age = 42, Weight = 185 },new { Name = "Andrea", Age = 46, Weight = 109 }
};
WriteLine(animals[0].ToString());
WriteLine(animals[0].GetHashCode());
WriteLine(animals[1].GetHashCode());
WriteLine(animals[2].GetHashCode());
WriteLine(animals[0].Equals(animals[1]));
WriteLine(animals[0].Equals(animals[2]));
WriteLine(animals[0] == animals[1]);
WriteLine(animals[0] == animals[2]);
ReadKey();

示例解释:

        当前的var animals=new [] 这里是使用了我们前面的类型推理,在当前这个匿名类型对象数组当中,我们创建了多个匿名类型。然后调用了几种不同的方法后输出结果。

        GetHashCode:返回一个对象的哈希码(整数数值)可以用于储存在哈希表等数据结构中。在数组当中的前两个有着相同的属性值,即返回的哈希值是相同的。

        Equals:匿名函数上就是比较一个对象的每个属性与另一个的对应属性值是否相同。如果相同则返回true。

        ==:比较比较对象引用。与方法Equals一致,但在匿名函数中的Equals不是一致。     

输出结果:

{ Name = Benjamin, Age = 42, Weight = 185 }
-1144474565
-1144474565
-977821549
True
False
False
False

提问:创建匿名类型时,如果是是多个相同类型的参数,会创建多个匿名类型吗?像我们前面扩展中创建的方式。


答:不会,会创建同一个匿名类型的多个实例。

动态查找

        动态查找:1 希望使用C#处理另一种语言创建的对象。2 处理未知类型的C#对象,如前一章使用了简单的反射来访问与类型关联的特性。

动态类型

动态类型我不好解释我们直接看它的定义方式,以及使用方式。

定义 (关键字dynamic)  :

public dynamic dongtaitype;

注意:        

        上述代码我们就已经定义了一个动态类型,但它与我们前面的var关键字不同var的关键字它并不是一个类型,而我们这里定义的'dongtaitype'它叫动态类型。一旦有了动态类型我们就可以继续访问其他成员。 

namespace MY
{class Program{public static dynamic dongtaitype;static void Main(){dongtaitype.ToString();}}
}

示例解释:我们这里直接用当前我们创建的动态类型直接调用了ToString方法。


注意:

        我这里并没有实现ToString方法也并没有给我们的动态类型进行一个初始化。所以它现在的值是"null" 。但编译器并不会报错。编译器还是会在运行的时候去调用这个方法,但当前变量是null所以这无法调用,编译器会抛出异常。


警告:我们在使用动态类型的情况下,我们尽量在只能使用动态类型的情况下再去使用它。如非.net对象,我的理解就是非C#语言创建的对象

接下来我大家看一个动态类型的例子(引在书上示例):

using Microsoft.CSharp.RuntimeBinder;
using static System.Console;
namespace My
{class MyClass1{public int Add(int var1, int var2) => var1 + var2;}class MyClass2 { }class Program{static int callCount = 0;static dynamic GetValue(){if (callCount++ == 0){return new MyClass1();}return new MyClass2();}static void Main(string[] args){try{dynamic firstResult = GetValue();dynamic secondResult = GetValue();WriteLine($"firstResult is: {firstResult.ToString()}");WriteLine($"secondResult is: {secondResult.ToString()}");WriteLine($"firstResult call: {firstResult.Add(2, 3)}");WriteLine($"secondResult call: {secondResult.Add(2, 3)}");}catch (RuntimeBinderException ex){WriteLine(ex.Message);}ReadKey();}}
}

示例解释:

        当前我们定义了两个类一个是MyClass1 一个是MyClass2 。其中MyClass1 当中我们定义了一个Add的一个方法。MyClass2 我们没有定义任何成员。在程序主入口Main函数当中我们定义了两个动态类型并且调用了返回动态类型的方法。那么在我们第一次调用GetValue这个方法的时候它会为我们返回一个MyClass1 的实例。在我们第二次调用的时候会返回一个MyClass2 的实例。随后我们使用我们拿到的动态类型去调用我们的ToString方法在这个我们是可以调用的,它实际是一个类型的实例化,当然也可以调用我们父类的ToString方法。那么重要的是我们输出语句的第三个输出语句,我们调用了一个Add的方法我们当前第一个动态类型是没有问题。但是下面那个MyClass2 的实例。这个动态类型它是无法调用因为它根本就没有当前方法。所以这里我们会抛出一个异常会提示“My.MyClass2”未包含“Add”的定义。 然后我们再对抛出的异常进行一个打印异常消息随后这个代码就结束了 

 高级方法参数

高级方法参数:允许使用命名参数和可选参数对方法的一个使用和定义

可选参数

定义方法时某些参数是可选的,而并非像常见方法的参数,要进行重载才能实现相同效果。

示例:

using System;
using Microsoft.CSharp.RuntimeBinder;
using static System.Console;
namespace My
{class Program{static void Main(string[] args){WStudent("zhangsan", 15);WStudent("李四");ReadKey();}#region 重载实现static void WrileStudent(string str){WriteLine(str);}static void WrileStudent(string str, int age){WriteLine(str + age);}#endregion#region 可选参数static void WStudent(string str, int age = 0){WriteLine(str + age);}#endregion}
}

示例解释:

        当前我们给”WrileStudent“方法提供了两个重载的方法。当然我们在下面又定义了一个效果相同的一个方法。其中int age=0 我们在这里其实就是定义了一个可选参数。我们在需要使用它的时候则给它传值,不需要可以直接忽略不传。

1 可选参数的值:默认值必须是:字面值、常量值、默认值类型值。

2 Optional特性:我们也可以使用当前特性定义可选参数

  static void WStudent(string str, [Optional] string ll, int age = 0){WriteLine(str + age+ ll);}

3 可选参数的顺序 :

  • 可选参数必须位于方法参数列表的末尾
  • 没有默认值的参数不能放在有默认值参数的后面 

命名参数

  //使用static void Main(string[] args){WStudent("李四", age: 10, ll: "");ReadKey();}//定义static void WStudent(string str, [Optional] string ll, int age = 0,int A=0,int B=10){WriteLine(str + age + ll);}

注意:使用方式时参数名+":"+值。


提示: 

        1 使用命令参数时可以指定需要的任意多个参数,而且参数的顺序是任意的。

        2 命名参数也是可选的 

        3 当方法签名中有多个可选参数和一些必选参数时,可以先指定必选参数,然后再指定需要使用到的可选参数。

Lambda表达式

         Lambda表达式是一种结构,简化C#编程的某些方面。Lambda表达式与其他的C#语言特性结合起来使用及其有用。如和匿名方法结合使用。

提示:匿名方法中 我们不要使用:My.lapsed+=Wrile; 这里是直接将一个方法赋值给事件。这样做会使代码更难理解也不清楚会发生什么  

把lambda表达式用于匿名方法

        在前面我们介绍了匿名方法的使用这里我将演示用lambda表达式替换匿名方法。在使用之前我有必要和你介绍lambda表达式的组成成分,分为三步。

第一部分:在括号当中放参数列表

第二部分:运算符

第三部分:我们的C#语句

举个例子:

using System;
using System.Timers;
namespace My
{class Program{static void Main(string[] args){Timer timer=new Timer(100);timer.Elapsed += delegate (object sender, ElapsedEventArgs e){//事件处理代码};//lambda 表达式替换匿名函数timer.Elapsed += (sender, e) => Console.Write("Hello");}}
}

示例解释:

        当前我们就做了一个lambda表达式替换匿名函数的一个示例。其中括号当中的就是我们的参数列表其他的部分也是按照我们上面所提到的三个部分所组成我们一个完整的lambda表达式 

Lambda表达式的参数

        Lambda表达式使用类型推理功能来确定所传递的参数类型。我们上述的一个示例并没有指定类型的情况下我们就是使用的它的一个类型推理功能,一个称为隐式类型化的Lambda表达式但如果我们指定了参数列表,当中的参数类型。那么它就被称为一个显示的Lambda表达式 

举个例子:

//显式lambda 表达式
timer.Elapsed += (object sender, ElapsedEventArgs e) => Console.Write("Hello");
//隐式lambda 表达式
timer.Elapsed += (sender, e) => Console.Write("Hello");

注意:

        1 在表达式当中你要么就全部显式类型要么就全部隐式类型。不能一个显式类型一个隐式类型 

        2 定义没有参数的 Lambda 表达式 则使用空括号来表达

举个例子:(sender) => Console.Write("Hello");

        3 定义单个参数的 Lambda 表达式 则不需要用括号  sender => Console.Write("Hello");

Lambda表达式的语句体

        我们其实可以在表达式的语句体中包含多个语句,为此我们就可以用花括号将我们的代码块放在其中。

举个例子:

timer.Elapsed += (object sender, ElapsedEventArgs e)=>
{ //放入代码块
};

        当我们lambda表达式 需要返回除void类型的其他类型,那么我们就要用上关键字 return 进行返回值,和我们在方法中一样。

提示(引入书上原文):如果需要多个语句则定义一个单独的非并匿名方法来代替lambda表达式比较好。

Lambda表达式用作委托和表达式树

        Lambda表达式其实是一个委托,你可以把Lambda表达式赋值给一个委托类型的变量。如我们前面的几个示例一样。但是在system名称空间中已经为我们提供了一些委托类型。所以在很多情况下我们都可以使用这些泛型委托类型而不必定义自己的泛型委托类型。

举例:

泛型类型参数列表个数返回类型
Action表示Lambda表达式     不带参数Void
Action<>表示Lambda表达式最多八个参数Void
Func<>表示Lambda表达式最多八个参数不是Void

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

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

相关文章

kotlin 基础概览

继承类/实现接口 继承类和实现接口都是用的 : &#xff0c;如果类中没有构造器 ( constructor )&#xff0c;需要在父类类名后面加上 () &#xff1a; class MainActivity : BaseActivity(), View.OnClickListener 空安全设计 Kotlin 中的类型分为「可空类型」和「不可空类型」…

基于ssm企业人事管理系统的设计与实现论文

摘 要 进入信息时代以来&#xff0c;很多数据都需要配套软件协助处理&#xff0c;这样可以解决传统方式带来的管理困扰。比如耗时长&#xff0c;成本高&#xff0c;维护数据困难&#xff0c;数据易丢失等缺点。本次使用数据库工具MySQL和编程技术SSM开发的企业人事管理系统&am…

Tekton 基于 gitlab 触发流水线

Tekton 基于 gitlab 触发流水线 Tekton EventListener 在8080端口监听事件&#xff0c;Gitlab 提交代码产生push 事件&#xff0c;gitlab webhook触发tekton流水线执行。 前置要求&#xff1a; kubernetes集群中已部署 tekton pipeline、tekton triggers以及tekton dashboa…

GO并发编程综合应用

一.GO并发编程综合应用 1.生产者消费者模式 1.1需求分析 ​ 生产者每秒生产一个商品&#xff0c;并通过物流公司取货 ​ 物流公司将商品运输到商铺 ​ 消费者阻塞等待商铺到货&#xff0c;需要消费10次商品 1.2实现原理 1.3代码实现&#xff1a; package mainimport (&q…

Unity Mono加密解决方案

Unity Mono 是 Unity 引擎默认的脚本运行时环境&#xff0c;在游戏开发中扮演着重要的角色。Mono 由跨平台的开源 .NET 框架实现&#xff0c;它允许开发者使用 C# 等编程语言编写游戏逻辑。凭借简单易用的开发环境和高效的脚本编译速度&#xff0c;得到了众多游戏的青睐。 在 …

基于亚马逊云科技新功能:Amazon SageMaker Canvas无代码机器学习—以构建货物的交付状态检测模型实战为例深度剖析以突显其特性

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在亚马逊云科技开发者社区、 知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道。 目录 &#x1f680;一. Amazon SageMaker &#x1f50e;1.1 新功能发布&#xff1a;A…

【通俗易懂】基于fabric8io操作k8s集群实战(pod、deployment、service、volume)

目录 前言一、基于fabric8io操作pod1.1 yaml创建pod1.2 fabric8io创建pod案例 二、基于fabric8io创建Service&#xff08;含Deployment&#xff09;2.1 yaml创建Service和Deployment2.2 fabric8io创建service案例 三、基于fabric8io操作Volume3.1 yaml配置挂载存储卷3.2 基于fa…

国际语音群呼系统有哪些应用场景?

国际语音群呼可应用于广告营销、消息通知、客情维护、金融催收等场景&#xff0c;助力出海企业产品营销和品牌推广。 广告营销 出海企业可以通过国际语音群呼系统&#xff0c;向目标市场的潜在客户进行广告宣传。例如&#xff0c;企业可以在系统中录制有关产品的宣传语&#…

分布式块存储 ZBS 的自主研发之旅|元数据管理

重点内容 元数据管理十分重要&#xff0c;犹如整个存储系统的“大黄页”&#xff0c;如果元数据操作出现性能瓶颈&#xff0c;将严重影响存储系统的整体性能。如何提升元数据处理速度与高可用是元数据管理的挑战之一。SmartX 分布式存储 ZBS 采用 Log Replication 的机制&…

InsCode实践分享

官方文档 官方文档永远是除了源码之外的最准确的资料&#xff0c;可以先看一遍&#xff0c;10分钟可以看完入门部分 InsCode 简介 | InsCode 文档 是什么 InsCode是一个在线的编程工具&#xff0c;提供了创建、调试、共享、部署项目的功能。可以说&#xff1a; InsCodeVSC…

Gitlab基础篇: Gitlab docker 安装部署、Gitlab 设置账号密码

文章目录 1、环境准备2、配置1)、初始化2)、修改gitlab配置文件3)、修改docker配置的gitlab默认端口 gitlab进阶配置gitlab 设置账号密码 1、环境准备 安装docker gitlab前确保docker环境&#xff0c;如果没有搭建docker请查阅“Linux docker 安装文档” docker 下载 gitlab容…

LabVIEW在高铁温度与振动监测中的应用

​LabVIEW在高铁温度与振动监测中的应用 高速铁路的可靠性和安全性是现代铁路运输系统设计和运营的重中之重。LabVIEW软件作为一个多功能、可扩展的图形编程环境&#xff0c;提供了一个理想的平台&#xff0c;用于开发高铁监测系统&#xff0c;不仅监测实时数据&#xff0c;也…

vue 中国省市区级联数据 三级联动

vue 中国省市区级联数据 三级联动 安装插件 npm install element-china-area-data5.0.2 -S 当前版本以测试&#xff0c;可用。组件中使用了 element-ui, https://element.eleme.cn/#/zh-CN/component/installation 库 请注意安装。插件文档 https://www.npmjs.com/package/ele…

Hudi 在 vivo 湖仓一体的落地实践

作者&#xff1a;vivo 互联网大数据团队 - Xu Yu 在增效降本的大背景下&#xff0c;vivo大数据基础团队引入Hudi组件为公司业务部门湖仓加速的场景进行赋能。主要应用在流批同源、实时链路优化及宽表拼接等业务场景。 一、Hudi 基础能力及相关概念介绍 1.1 流批同源能力 与H…

Yum仓库架构解析与搭建实践

1.Yum仓库搭建 1.1本地Yum仓库图解 1.2Linux本地仓库搭建 配置本地光盘镜像仓库 1&#xff09;挂载 [roothadoop101 ~]# mount -t iso996 /dev/cdrom/mnt 2&#xff09;查看 [rooothadoop101 ~] # df -h | |grep -i mnt /dev/sr0 4.6G 4.4G 3&#xf…

python学习1

大家好&#xff0c;这里是七七&#xff0c;今天开始又新开一个专栏&#xff0c;Python学习。这次思考了些许&#xff0c;准备用例子来学习&#xff0c;而不是只通过一大堆道理和书本来学习了。啊对&#xff0c;这次是从0开始学习&#xff0c;因此大佬不用看本文了&#xff0c;小…

103基于matlab的极限学习机(ELM)和改进的YELM和集成极限学习机(EELM)是现在流行的超强学习机

基于matlab的极限学习机&#xff08;ELM&#xff09;和改进的YELM和集成极限学习机(EELM)是现在流行的超强学习机&#xff0c;该程序是三者的方法比对。 包括学习时间&#xff0c;训练精度和测试精度的对比。数据可更换自己 的&#xff0c;程序已调通&#xff0c;可直接运行…

Nginx+Tomcat实现负载均衡和动静分离

目录 前瞻 动静分离和负载均衡原理 实现方法 实验&#xff08;七层代理&#xff09; 部署Nginx负载均衡服务器(192.168.75.50:80) 部署第一台Tomcat应用服务器&#xff08;192.168.75.60:8080&#xff09; 多实例部署第二台Tomcat应用服务器&#xff08;192.168.75.70:80…

Django和ECharts异步请求示例

前提条件 创建django项目&#xff0c;安装配置过程这里就不讲述了。 后端url http://127.0.0.1:8000/echarts/demo/ view视图函数 from django.http import HttpResponse import jsondef EchartsDemo(request):data {}categories ["衬衫","羊毛衫",&…

初识数据结构

文章目录 一、什么是数据结构&#xff1f;二、什么是算法&#xff1f;三、数据结构和算法的重要性在校园招聘的笔试中在校园招聘的面试中某学长CVTE面试&#xff1a;某学长腾讯的面试&#xff1a;某学姐百度的面试&#xff1a; 在未来的工作中 四、如何学好数据结构和算法1.死磕…