当前位置: 首页 > news >正文

第二阶段WinFrom-7:文件操作补充,泛型复习,协变和逆变

1_文件操作补充

(1)判断文件是否隐藏

OpenFileDialog openFileDialog = new OpenFileDialog();
FileInfo fileInfo = new FileInfo(openFileDialog.FileName);
//如果文件隐藏,输出Hidden, Archive;文件未隐藏输出Archive
Console.WriteLine(fileInfo.Attributes);//Hidden, Archive
// & 与运算,fileInfo.Attributes输出为Hidden, Archive,则fileInfo.Attributes & FileAttributes.Hidden结果为Hidden
//fileInfo.Attributes输出为Archive,则fileInfo.Attributes & FileAttributes .  Hidden 结果为0
Console.WriteLine((fileInfo.Attributes & FileAttributes.Hidden));
//HasFlag 判断 Attributes属性中是否包含某个枚举
Console.WriteLine(fileInfo.Attributes.HasFlag(FileAttributes.ReadOnly));

(2)Process类,能够对本地的进程进行操作

Start:启动或重用指定的进程;参数1可以是快捷方式,也可以时应用程序 .exe;参数2指定打开的应用的界面

//Process类 能够对本地的进程进行操作
//防抖  节流     防呆
for (int i = 0; i < 5; i++)
{
//打开文件Process.Start(@"D:\Tencent\QQNT\QQ.exe");
}
//参数2指定打开的应用的界面
Process.Start(@"C:\Program Files\Google\Chrome\Application\chrome.exe", "https://www.baidu.com");

2_泛型的概念,定义,运行原理,优势

(1) 概念:泛型是C#2.0推出的新语法,它是专门为处理多段代码在不同的数据类型上执行相同的指令的情况而设计的。

泛型让不同的数据支持相同的业务逻辑; 泛型是一个符复合数据类, 把多个类型混合在一起使用,比如方法和泛型混到一起就是泛型方法, 类和泛型混合一起就是泛型类,接口和泛型混合到一起就是泛型接口

List<T>,  如:List<int>  ints = new List<int>(){10,11,12}

(2)泛型定义语法格式

<T>或<T,K,......> 其中T,K指未知类型。 T,K,M,N 泛型定义时,是延迟声明的:即定义的时候没有指定具体的参数类型,把参数类型的声明推迟到了调用的时候才指定参数类型。

(3)运行原理: 程序最终会编译成XXX.exe,XXX.exe被点击的时候,会经过JIT的编译,生成二进制代码,才被计算机执行。使用泛型以后,VS自带的编译器又做了升级,升级之后编译时遇到泛型,会做特殊的处理:先生成占位符。再次经过JIT编译的时候,会把上面编译生成的占位符替换成具体的数据类型。

JIT:Just In Time称为即时编译器

(4)泛型优势:速度快且支持不同类型。 a.最大限度地重用代码;b.保护类型的安全以及提高性能;c.语法优美

(5)泛型应用范围:泛型方法,泛型类,泛型接口,泛型委托,泛型结构

(6)泛型约束:

泛型的目的,相同的业务逻辑,支持了不同类型。如果一味的滥用,对代码安全性不利。引入泛型约束主要控制泛型支持的类型在有限的范围内。所谓的泛型约束,实际上就是约束的类型T。使T必须遵循一定的规则。比如T必须继承自某个类,或者T必须实现某个接口等等。

五种常用的泛型约束

约束说明
where T:class引用类型约束保证T一定是引用类型的。
where T:struct值类型约束保证T一定是值类型的。
where T:new()无参数构造函数约束保证T必须有无参数构造函数,无参构造函数约束和其他约束搭配使用时,new()要放到最后。
where T:接口名称接口约束保证T必须实现接口
where T:基类名基类约束时,基类不能是密封类,即不能是sealed类。sealed类表示该类不能被继承,在这里用作约束就无任何意义,因为sealed类没有子类。

泛型约束可以同时约束多个。如:where T : People, ISports 要求T必须是People或People的子类,或同时实现ISports接口。

3_协变和逆变

(1)协变和逆变是在.NET 4.0的时候出现的,协变和逆变只能发生在泛型接口或者泛型委托中。

  • 协变(covariant):IFoo<父类> = IFoo<子类>;out,用来修饰返回值

  • 逆变(contravariant):IBar<子类> = IBar<父类>;in,用来修饰传入参数

(2)协变和逆变其实也是类型变化。

  • C#类型转换发生在单一类型中,如:小范围类型的int隐式转换成大范围类型long,大范围类型long强制转换成小范围类型int。

  • 而泛型的协变和逆变,只发生在泛型中。泛型不是单一类型。如:List<T> List是数据类型,T也是数据类型。泛型可以认为是复合类型。

  • 协变:类似于隐式类型转换,但有所不同。【协变控制的是返回值的类型】。如:public interface IEnumerable<out T> 逆变:类似于强制类型转换,但有所不同。【逆变控制的是传入参数的类型】。如:public delegate bool Predicate<in T>(T obj)

  • 协变和逆变只能发生在泛型接口或者泛型委托中,类型转换没有此限制。

(3)使用了协变以后,=左边声明的是基类,右边可以声明基类或者基类的子类。简单理解:即小转大。 如:协变 IEnumerable<Bird> birdList1 = new List<Bird>(); IEnumerable<Bird> birdList2 = new List<Sparrow>();

(4)不论协变或逆变,发生在复合类型之间,不会发生单一类型之间。 错误理解:不要理解成Sparrow继承Bird,所以new List<Sparrow>()可以赋值给IEnumerable<Bird>了。理解有偏差。 List<Sparrow>和IEnumerable<Bird>之间的关系。为什么List<Sparrow>实例可以赋值给IEnumerable<Bird> 类型。原因:IEnumerable<out T>

(5)使用了逆变之后,=左边声明是子类,右边可以声明子类或者子类的基类。简单理解:即大转小。

http://www.dtcms.com/a/354116.html

相关文章:

  • Python LangChain RAG从入门到项目实战09.:LangChain 中的 Retriever(检索器)
  • buuctf——web刷题第5页
  • Vue2 基础用法
  • CVPR深度学习研究指南:特征提取模块仍是论文创新难点
  • 吴恩达机器学习作业二:线性可分逻辑回归
  • CMake构建学习笔记21-通用的CMake构建脚本
  • Liunx内核驱动
  • Java中StringBuilder原理以及使用
  • D4145低功耗GFCI接地故障控制芯片介绍
  • 题目—移除元素
  • 作业帮,途虎养车,得物,途游游戏,三七互娱,汤臣倍健,游卡,快手26届秋招内推
  • JUC多线程个人笔记
  • 【DC工具GUI入门】
  • APP测试全流程以及测试点
  • 【开题答辩全过程】以 基于SpringBoot的流浪动物领养系统的设计与实现 为例,包含答辩的问题和答案
  • 从Java到Go:初遇Go语言的震撼体验
  • 力扣 30 天 JavaScript 挑战 第41天 (第十二题)对异步操作,promise,async/await有了更深理解
  • 【Linux实时内核机制】ww_rt_mutex 的contending_lock异常问题
  • android/java中主线程和子线程的详解
  • Nano Banana揭秘:Google Gemini 2.5 Flash Image正式发布 | AI图像编辑新时代
  • 内网应用如何实现外网访问?外地通过公网地址访问内网服务器的设置方法
  • 动态规划:青蛙跳台阶实践
  • H20 性能表现之 Kimi-K2
  • 【git】:gitee项目管理vs2019
  • 装饰器进阶与设计模式
  • Linux入门教程 第十五章 Linux 系统调优工具
  • 【工具篇】github/huggingface 镜像源总结
  • 嵌入式系统学习Day24(线程)
  • Custom SRP - Shadow Masks
  • Axure:如何将SVG转换为形状