c#个人向总结

c#个人向简单总结


前言:由于博主了解过c,java,c++,所以下面在总结时会略过相似的,只总结了自己不熟的部分


文章目录

  • c#个人向简单总结
    • 入门level1
      • 输入与输出
      • 基础变量
      • 强转方式
      • 控制台进阶
      • 随机数使用
    • 基本level2
      • 数组
      • 函数
    • 核心level3
      • 垃圾回收机制GC
        • 简要理解
        • 手动触发
      • 类class
        • 成员属性:保护成员变量
        • 构造函数
        • 索引器
        • 分布partial
        • 类和结构体的比较
      • 静态static
        • static和const的区别
        • 静态构造函数
        • 拓展方法:写在静态类中的一个静态方法
        • 运算符重载operator:一定为公共静态方法
      • 继承
        • is和as关键字
        • 密封sealed
      • 多态vob = 虚函数virtual + 重写override + 父类指针base
      • 抽象abstract和接口interface
        • 抽象类和接口的比较
        • 抽象方法和虚方法的比较
      • 万物之父Object
    • 进阶level?
      • 泛型<>
        • 泛型约束`where`
        • 协变out与逆变in
      • 数据结构(容器?)
      • 委托delegate
        • 系统自带委托
        • 事件event
        • 匿名函数与lambda表达式
        • List自定义排序
        • 多线程Thread
      • 反射
        • Type类
        • Activator类
        • Assembly程序集类
      • 特性[]
        • 特性相关方法
        • 系统自带特性
      • 迭代器iterator
      • 其他语法

入门level1

输入与输出

#region//折叠,中间放内容Console.WriteLine("helloworld");//输出
Console.ReadLine();//输入#endregion

基础变量

sbyte, int, short, long//有符号
byte, uint, ushort, ulong//无符号
float, double, decimal//浮点数,隐式转换中的decimal不能存其他两个浮点数
bool, char, string//其他,char为2字节

强转方式

  • c语言同款括号()直接转
  • int.Parse(要转的内容)
  • Convert.ToXXX(要转的内容),XXX为具体的类型

控制台进阶

Console.ReadKey(true).keyChar;//常用于不显示在控制台的单字符获取
Console.Clear();//清空控制台
Console.SetWindowSize(x, y);//设置窗口大小
Console.SetBufferSize(x, y);//设置窗口缓冲区大小
Console.SetCursorPosition(x, y);//设置光标位置
Console.ForegroundColor = ConsoleColor.Red;//设置文字颜色,Red可替换
Console.CursorVisible = false;//光标显示隐藏
Enviroment.Exit(0);//关闭控制台

随机数使用

Randomnew一个变量r,随后用r.Next(x. y)=》随机生成一个x(包含)到y(不包含)间的数

基本level2

数组

int[] a;//一维
a.length;//获取长度int[,] a;//二维(真反人类。。)
a.Getlength();//参数为0时获取行长度,为1时获取列长度int[][] a;//交错,意思是列的长度不固定,行的长度固定(你不是有两个括号的吗,就不能把上面那个改成交错这个改成二维吗。。。)
//获取行的长度时与二维数组一致,但获取列的长度时与一维数组一致,其实这样获取可以推测他底层的实现了。。。

函数

  • 传实参修饰符
    • ref:必须在传入前初始化
    • out:必须在函数内部进行赋值
  • 变长参数params
  • 可以给参数赋默认值,并且函数存在重载

核心level3

垃圾回收机制GC

简要理解

C#中采用分代算法,将内存分为0代1代2代内存

其中大部分新分配内存的对象都会放在0代内存中,当0代内存分配满后,GC会开始检查每个分配的对象上是否有标记可达(还在用,比如说还有引用指向堆中的对象,则视为可达),若不可达,则将这些不可达的视为垃圾释放,而可达的则会搬迁到1代内存

同样,如果1代内存满了,则会进行相同的过程,不同的是,此时0代也会一起释放

而为了避免过于频繁地触发GC,大对象(80多kb以上)创建时会直接放到2代内存中

手动触发

GC.Collect(),通常用于场景切换时手动释放,避免在游戏过程中触发GC让玩家感到卡顿

类class

成员属性:保护成员变量
class Test{public Name{get;//写方法体时需要returnset;//写方法体时关键字value表示传入内容}//内部两个方法可以通过添加访问修饰符达到只能读不能改的效果
}
构造函数

构造函数可以在后跟上:调用其他构造函数进行一部分初始化内容

class Test{int age;int height;Test() {age = 0;}Test(int height):Test() {this.height = height;//this和常见语言中一样,指类自己}
}
索引器
class Test{int[] a;Test() {a = new int[30];}public int this[int i] {return a[i];}
}

可以在外部使用类名[x]直接赋值

分布partial

修饰类时可以分开几部分写一个类,不能有重复成员,访问修饰符要一致

修饰方法时可一边声明一边实现

类和结构体的比较
  • 结构体是个值对象,在栈区;类是个引用对象,在堆区
  • 结构体不能用protected修饰符,不能给成员变量赋初值,不能自己写无参构造,而类没有这三点限制
  • 基于上面这三点,自然,结构体有了有参构造后无参构造不会被顶掉,且在有参构造中必须初始化所有成员,而类这样做会顶掉无参,不用一次性初始化所有成员
  • 因为结构体在栈区,所以它没有析构函数,没有静态,类有
  • 结构体不能继承结构体,但是可以继承接口
  • 结构体不能将自己的struct作为成员,类可以这样做(但这样声明自己有点吓人了,一不小心就无限递归爆栈了)

选择:数据集合和经常要改变赋值但原对象不想变的可以用struct,要继承多态的用class

静态static

static和const的区别

const常量必须初始化且不能更改,只能修饰变量,不能写在访问修饰符前,static没有这些限制

静态构造函数
  • 不能有访问修饰符和参数
  • 只调用一次,主要用于初始化静态成员
  • 普通类也可以有
拓展方法:写在静态类中的一个静态方法

主要用于为非静态类型添加方法

public static void Develop(this int value, 参数1, 参数2, ...) {}
//此例是为int类添加一个叫做Develop的方法,this必须写在第一个正是参数前,this后跟着要添加方法的类
运算符重载operator:一定为公共静态方法
  • 条件运算符要成对实现,比如重载了==就必须同时重载!=
  • 不能用refout
public static 返回值 operator 运算符(参数){}
//书写规则与c++一致

继承

用法与c++一致,直接子类:父类,不过又和Java一样是单继承(。。。。)

is和as关键字

is用于判断对象,as用于转换对象(比如里氏替换遍历时遇到父类装子类对象,要调用子类特有的方法,可使用as

密封sealed

修饰类时即不允许继承该类

修饰从父类重写的方法时不让自己的后代再重写

多态vob = 虚函数virtual + 重写override + 父类指针base

virtualoverride配合使用,子类可重写父类中的虚函数,重写后想用父类中的该方法可用base调用

抽象abstract和接口interface

abstract修饰的类即抽象类不能实例化,和Java一样可以多继承接口

抽象类和接口的比较

相同点:

  • 都可以被继承,都不能实例化
  • 都可以由方法的声明,子类必须实现其未实现的方法
  • 都遵循多态

不同点:

  • 前者有构造函数,后者无
  • 前者单继承,后者多继承
  • 前者可以有成员变量,后者不行
  • 前者可以声明成员方法,虚方法,抽象方法以及静态方法,后者只能声明抽象方法
  • 前者的方法随便写访问修饰符,后者建议不写,默认未公共

选择:表对象选前者,行为拓展用后者

抽象方法和虚方法的比较

最主要区别:虚方法子类可选择性重写,抽象方法(相当于c++里的纯虚方法=0)子类必须重写

万物之父Object

  • 成员方法GetType():后面说,反射的重点
  • 成员方法MemberwiseClone():浅拷贝,返回新的对象(其内部的引用对象成员与老对象一致)
  • 虚方法toString():可以自己实现一个,但大多数情况没必要
  • 虚方法Equals():不重新实现它就是静态方法,默认比较是否为同一引用,如果要自定义比较就是虚方法(。。。)

Object存值为装箱,把其内值取出来as了为拆箱,多态的最大受益者

插曲提一嘴:StringBuilder比起String效率上的优势,主要在于修改而不是创建,会自动扩容,要用的时候再查提供的方法

进阶level?

泛型<>

和Java那个几乎没区别

泛型约束where

顾名思义,限制泛型修饰的范围,放在后面就行

class Test<T> where T:class{}

这个where后面的class可以替换来限制不同类型,可以一次写几个也没关系,如果有多个泛型多写几个where也可以

值类型:struct;引用类型:class;存在公共无参构造函数new()

某个类或者它娃:类名;某个接口或者它娃:接口名;另一个泛型类型或派生:另一个泛型字母

协变out与逆变in

也是修饰泛型的,限制泛型作用的地方

协变out:修饰后的泛型只能作为返回值

逆变in:修饰后的泛型只能作为参数

除此之外,协变是和谐的变化,逆变不和谐,协变修饰后是正常的父类装子类,遵循里氏替换,而被逆变修饰后子类可以去装父类

数据结构(容器?)

  • ArrayList:本质为Object数组
  • HashTable:哈希表,本质同上
  • StackQueue:不用泛型的时候本质同上,用泛型的重载时本质是泛型数组
  • List:本质为泛型数组
  • Dictionary:字典,本质同上
  • LinkedList/LinkedListNode:本质为泛型双向链表,可以从字面意思上看出是有头和身子区分的

委托delegate

装函数名的,用invoke()方法调用或者直接()也行,函数指针的包装版(太掉价了。。。)

自定义委托在一个正常的函数声明前加delegate即可

可以做加减法运算,装多个函数,调用时一起调用,也可以清空

系统自带委托
  • Action:无参无返回值
  • Func<T>:无参有返回值
  • Action<T,...>:有参无返回值(泛型指定参数)
  • Func<T,T,...>:有参有返回值(第一个泛型仍为返回值)
事件event

和委托一个效果,但是更安全,在委托外面再包装一层,定义时public event 定义好的委托名 事件名

  • 只能在类,接口,结构体中定义
  • 不允许外部赋值调用
匿名函数与lambda表达式

通常和委托配套使用

//匿名函数
Action a = delegate(){函数逻辑};
//lambda表达式
Action a = (参数)=>{函数逻辑};
List自定义排序
  • 法一:要排序的类继承IComparable接口,实现其中的CompareTo()方法(以类的自定义为例,通常需要传入另一个类作为other与本类this比较)

  • 法二:使用List自带的Sort方法重载,传入逻辑比较函数

    list.Sort((a, b)=>{return a.id > b.id ?1 : -1;});
    
多线程Thread
Thread t = new Thread(要开线程的函数);
//线程方法
t.Start();//开启线程
t.isBackground = true;//后台运行
Thread.Sleep(时间);//线程休眠
lock(obj){逻辑}//obj为任意Object对象,其他也可以,在不同线程内加入lock关键字,可以让线程达到交替执行的效果

反射

运行中获取程序集(源文件内容)

Type类

获取Type

  • Object万物之父类中的方法GetType()
  • typeof(类名)关键字
  • 通过类名Type.GetType("哪个命名空间里的类名")

获取对象里的信息:

Type t = typeof(Test);
MemberInfo[] x = t.GetMembers();//获取所有公共成员
ConstructorInfo[] x = t.GetConstructors();//获取所有构造函数
FieldInfo[] x = t.GetFields();//获取所有公共成员变量
MethodInfo[] x = t.GetMethod();//获取所有公共方法//获取某个具体的成员变量时,把后面的s后缀去掉即可,()内填要获取成员的字符串随后可通过GetValue()和SetValue()方法直接操控值//获取某个具体的成员方法时,除了和上面一样,若存在重载还需传第二个参数new Type[]{参数列表的type},获取完毕执行时用Invoke()方方法,静态方法参数传null,非静态第一个参数填要执行这个方法的对象,第二个参数new object[]{参数列表}

获取对象:

//三步走:要得到哪个构造函数=》实例化上面得到的构造函数得到object对象=》as后获取最终对象
ConstructorInfo x = t.GetConstructor(new Type[]{});//获得无参构造
//若要获取有参构造,在{}内填写要获取构造函数的参数type
object obj = x.Invoke(null);//有参构造时传入参数即可,这一步为实例化获取对象
Test test = obj as Test;
//当然上面两步也可以简写为一步
Test obj = x.Invoke(null) as Test;
Activator类

Type中获取对象的方法太麻烦了,所以有这个一步到位的快速实例化

Test obj = Activator.CreateInstance(typeof(Test), 参数列表) as Test;
Assembly程序集类

加载程序集:

//加载同一文件下
Assembly assembly = Assembly.Load("程序集名称");
//加载不同文件下
Assembly assembly = Assembly.LoadFrom("包含程序集的文件名称或路径");
Assembly assembly = Assembly.LoadFile("要加载文件的完全限定路径");//assembly有GetType("类名")方法

有了程序集后就可以用TypeActivator部分的知识实例化对象了

特性[]

Java的注解,为元数据添加额外信息

自定义特性需要定义一个类去继承Attribute

特性相关方法
Type t = typeof(Test);
t.IsDefined(typeof(特性名), false);//是否使用特性,第二个参数为是否搜索后代
object[] x = t.GetCustomAttributes(true);//获取所有特性
系统自带特性
  • 限制使用范围[AttributeUsage(AttributesTargets.Class, AllowMultiple = true, Inherited = true)]:三个参数依次为能用的地方(若要加多个能用的地方,使用|连接),是否允许多个特性用在一个目标上,特性能否被后代继承
  • 过时[Obsolete("提示信息", true)]:第二个参数为true时报错,false时警告
  • 条件编译[Conditional("函数名")]:只有define过该函数,调用该函数时才会执行
  • 调用者信息[Caller]:包括[CallerFilePath][CallerLineNumber][CallerMemberName],报错时报的更清楚
  • 外包调用[DllImport]:标记的函数说明它在一个外部的DLL中定义

迭代器iterator

foreach的底层实现,比方说foreach(int i in list),就会先通过GetEnumerator方法获取IEnumerator,再执行其中的MoveNext方法,返回为true则获取Current赋值给i

自定义迭代器实现需继承IEnumberableIEnumerator两个接口,并实现下面四个方法(示例)

class Test:IEnumberable, IEnumerator {public int position = -1;//模拟光标private int[] list;public Test() {list = new int[]{1, 2, 3};}public IEnumerator GetEnumerator() {Reset();return this;}public object Current{get {return list[position];}}public bool MoveNext() {position++;return position < list.Length;}public void Reset() {position = -1;}
}

或者除了上面基于基本原理的实现,还可以使用yield语法糖实现,仅需实现一个方法(挺奇妙的)

public IEnumerator GetEnumerator() {for (int i = 0; i < list.Length; i++) {yield return list[i];}
}

其他语法

  • var用于偷懒
  • 形如python的内嵌字符串Console.WriteLine($"{name},{age}")
  • 奇怪的?语法糖,比如int? a = null是合法的(真的有正常人这么写吗),见到再查吧

完结撒花,谢谢你的阅读么么叽

参考或者说学习来源:b站唐老狮

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

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

相关文章

day 16

创建链接文件 软链接&#xff1a;又叫符号链接&#xff0c;类似win的快捷方式&#xff0c;是一种用来建立文件的特殊文件&#xff0c;这个文件里的数据都是建立链接的文件&#xff0c;但是它和建立链接的文件不是一个东西&#xff0c;如果建立链接的文件移动或删除&#xff0c…

fork系统调用

基本概念&#xff1a; 在操作系统里&#xff0c;进程是正在运行的程序的实例。fork() 函数的作用是复制当前进程&#xff0c;生成一个新的进程&#xff0c;这个新进程被称作子进程&#xff0c;而原本的进程则是父进程。这两个进程&#xff08;父进程和子进程&#xff09;会从 …

【leetcode刷题记录】(java)数组 链表 哈希表

文章目录 四、题目之&#xff1a;代码随想录(1) 代码随想录&#xff1a;数组[704. 二分查找](https://leetcode.cn/problems/binary-search/)[27. 移除元素](https://leetcode.cn/problems/remove-element/)暴力解:双指针&#xff1a; [977. 有序数组的平方](https://leetcode.…

在线运行vscode

安装 https://github.com/coder/code-server?utm_sourcesyndication&pubDate20250317 运行前预览脚本 curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-run运行脚本 curl -fsSL https://code-server.dev/install.sh | sh其他 可以通过后台服务运行&am…

【Tauri2】002——Cargo.toml和入口文件

目录 前言 正文 toml文件的基础 注释——# Comment 键值对——Key/Value 表——[table] 内联表——Inline Table 数组——Array package和crate Cargo.toml文件 Cargo.toml——dependencies Cargo.toml——lib crate-type main.rs 前言 【Tauri2】001——安装及…

Netty源码—7.ByteBuf原理三

大纲 9.Netty的内存规格 10.缓存数据结构 11.命中缓存的分配流程 12.Netty里有关内存分配的重要概念 13.Page级别的内存分配 14.SubPage级别的内存分配 15.ByteBuf的回收 9.Netty的内存规格 (1)4种内存规格 (2)内存申请单位 (1)4种内存规格 一.tiny&#xff1a;表示从…

W、M、C练题笔记(持续更新中)

web here are the flag 点击&#xff0c;页面跳转404.php&#xff0c;用bp抓包访问/flag.php页面&#xff0c;得到flag用base64解码 TryToFindFlag 打开后查看源代码 发现是robots协议&#xff0c;访问robots.txt 访问flllaaa......&#xff0c;得到空白页面&#xff0c;查看…

【高项】信息系统项目管理师(十二)项目干系人管理【3分】

项目干系人管理包括识别能够影响项目或会受项目影响的人员、团队或组织,分析干系人对项目的期望和影响,制定管理策略有效调动干系人参与项目决策和执行。项目干系人管理过程能够支持项目团队的工作。一、管理基础 1、管理的重要性 项目经理和团队管理干系人的能力决定着项目…

Keil(ARMCC)编译改为Cmake(GNU)编译

1. 环境介绍&#xff1a; 某款ARM-M4芯片&#xff08;应该芯片通用&#xff09;cmkeGNUNinja&#xff08;CLion&#xff09; 2. 必备&#xff1a; 芯片启动文件 startup_xxxx.s链接文件 xxxx_flash.ldCMakeLists.txt 3. 具体修改步骤 第一步&#xff1a;观察启动文件…

SpringCould微服务架构之Docker(4)

Docker ce是社区版。 安装docker之前&#xff0c;先安装yum-util 。 安装docker之前&#xff0c;一定要先关闭防火墙。

LangChain开发(四)服务监控(LangSmith、verbose、debug)

文章目录 LangChain服务监控LangSmith Tracing&#xff08;跟踪&#xff09;Verbose&#xff08;1详细日志打印&#xff09;Debug&#xff08;调试日志打印&#xff09;源码地址参考资料 LangChain服务监控 与构建任何类型的软件一样&#xff0c;使用LLM构建时&#xff0c;总会…

从车间到数字生态:MES如何引领制造业智能化革命‌

在全球制造业加速迈向工业4.0的浪潮中&#xff0c;传统生产模式正经历颠覆性变革。制造执行系统&#xff08;MES&#xff09;作为连接物理车间与数字世界的核心纽带&#xff0c;正从“生产辅助工具”升级为“智能决策大脑”&#xff0c;推动制造业向数据驱动、柔性化与可持续化…

人工智能之数学基础:瑞利商的推广形式——广义瑞利商

本文重点 在数学和工程领域,瑞利商(Rayleigh quotient)的推广形式——广义瑞利商(Generalized Rayleigh quotient)扮演着重要的角色。它们不仅为线性代数中的特征值问题提供了新的视角,还在信号处理、机器学习、计算机视觉等领域有广泛的应用。 广义瑞利商的定义 广义…

【QT】QT中的中文显示乱码解决

QT中的中文显示乱码解决 1.编辑栏左键——>选择编码 2.选择UTF-8—>按编码重新载入 3.工具栏左键—>选择选项 4.同样选择UTF-8—>确定即可

优选算法系列(4.前缀和 _下) k

目录 五&#xff1a;和为 k 的子数组&#xff08;medium&#xff09; 题目链接&#xff1a;560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; 代码&#xff1a; 六&#xff1a;和可被 K 整除的子数组&#xff08;medium&#xff09; 题目链…

批量处理word里面表格的空白行

1&#xff0c;随便打开一个word文档。 2&#xff0c;按下Alt F11 VBA编辑器,在左侧的「工程资源管理器」窗口中找到Normal 项目,右键选择插入->模块。 弹出一下弹窗 3&#xff0c;输入一下代码 代码&#xff1a; Sub RemoveEmptyTableRows()Dim tbl As TableDim row As R…

《Linux运维实战:Ubuntu 22.04使用pam_faillock实现登录失败处理策略》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;Linux运维实战总结 一、背景信息 在ubuntu 22.04中&#xff0c;pam_tally2模块已被弃用&#xff0c;取而代之的是pam_faillock模块。因此&#xf…

如何通过数据可视化提升管理效率

通过数据可视化提升管理效率的核心方法包括清晰展示关键指标、及时发现和解决问题、支持决策优化。其中&#xff0c;清晰展示关键指标尤为重要。通过数据可视化工具直观地呈现关键绩效指标&#xff08;KPI&#xff09;&#xff0c;管理者能快速、准确地理解业务现状&#xff0c…

Qt的文件操作

Qt的文件操作 由于 Qt 的发展比较早&#xff0c;在 C 尚未提供标准的文件流操作时&#xff0c;Qt 就研发出了自己的文件操作并沿用至今。Qt 提供了丰富的文件操作类&#xff0c;包括 QFile 文件操作和读写类以外&#xff0c;还有 QSaveFile&#xff08;安全文件保存类&#xf…

Netty源码—7.ByteBuf原理四

大纲 9.Netty的内存规格 10.缓存数据结构 11.命中缓存的分配流程 12.Netty里有关内存分配的重要概念 13.Page级别的内存分配 14.SubPage级别的内存分配 15.ByteBuf的回收 13.Page级别的内存分配 (1)Page级别的内存分配的入口 (2)Page级别的内存分配的流程 (3)尝试在现…