Java基础学习C#

发布时间 2024-01-09 17:51:49作者: Jackpot_ABC

一、 .Net框架

1、什么是.Net框架

微软开发平台——.net的核心,主要用于为运行windows系统的计算机开发应用程序
ps: .NET Core 则是一个跨平台的框架

2、.Net框架的组成

.Net框架的组成

3、特点

1)面向对象的开发环境

2)自动垃圾收集

3)互操作性
①不同的.net语言编写的程序可以相互调用或继承
②提供平台调用的特性,可以调用非.net的代码,如Windows API
③能与COM组件相互调用(系统中还在使用很多COM组件)

4)不需要COM(Component Object Model,组件对象模型)

5)简化的部署
①不需要使用注册表注册,最简单的情况下,只要把程序复制过去即可运行
②提供并行执行的特性,允许一个DLL的不同版本在同一台机器上存在,意味着每个可执行程序都可以访问程序生成时使用的那个版本的DLL(比如一个程序分为普通版和会员版,普通版使用普通版的DLL,会员版使用会员版的DLL,该DLL的版本号不同)

6)类型安全性
CLR检查并确保参数及其他数据对象的类型安全,包括不同编程语言编写的组件之间

7)提供了一个庞大的基类库(BCL)
①如通用基础类:文件操作、字符串操作、安全和加密
②集合类:列表、字典、散列表、位数组
③线程和同步类:用于创建多线程程序
④XML类:创建、读取和操作XML文档

4、编译过程

.net语言的编译器接受源代码文件,并生成名为程序集的输出文件

编译过程

1)程序集要么是可执行的,要么是DLL
2)程序集中的代码不是本机代码,而是CIL(Common Intermediate Language,公共中间语言)
3)程序集中包括:
①程序的CIL
②程序中使用的类型的元数据
③对其他程序集引用的元数据

ps: 元数据——描述在代码中定义的每一类型和成员,二进制形式

5、编译成本机代码并执行的时机

程序的CIL被调用运行时,才会被编译成本机代码,然后被缓存起来供后续调用(不被调用的代码不会被编译成本机代码,被调用的代码只编译一次)

在运行时,CLR执行以下步骤:
1)检查程序集的安全特性
2)在内存中分配空间
3)把CIL发送给即时编译器(JIT)把其中一部分编译成本机代码

运行时被编译成本机代码

被编译成本机代码之后,CLR就在它运行时时管理它,如释放内存,检查数组边界,检查参数类型和管理异常之类的任务

引申出两个术语:
1)托管代码;为.net框架编写的代码称为托管代码,需要CLR
2)非托管代码;不在CLR控制之下运行的代码

编译和执行过程
编译时和运行时过程

6、CLR概览(.NET框架的核心组件)

负责管理程序的执行,提供
①自动垃圾收集
②安全和认证
③通过访问BCL得到广泛的编程功能

CLR概览

7、CLI(公共语言基础结构)

1、定义:

将.NET框架所有组件连结成一个内聚的、一致的系统的一组标准,展示了系统的概念和架构,并详细说明了所有软件都必须遵循的规则和约定

CLI的组成

2、了解CLI的重要组成部分

1)CTS(公共类型系统)

定义了在托管代码中一定会使用的类型的特征

2)CLS(公共语言规范)

详细说明了一个.NET兼容编程语言的规则、属性和行为,其主题包括数据类型、类结构和参数传递

一、C#项目结构

1. 解决方案

解决方案文件:.sln文件,含有
1)开发工具的版本,最低版本
2)当前解决方案中含有的项目,以及项目的id,项目名称,项目文件路径
3)含有项目的发布调试编译方式定义

2. 项目(即程序集)

项目文件:.csproj文件,含有
1)当前项目的框架类型,框架版本
2)当前项目的引用程序集和版本

默认情况下:项目名称=程序集名称=项目的根命名空间名称

3. 程序集概念(Assembly)

程序集是一个或多个类型定义文件及资源文件的集合(可以看作是打了个jar包)
程序集包含:
1) 资源文件
2) 类型元数据(描述在代码中定义的每一类型和成员,二进制形式)
3) IL代码(这些都被封装在exe或dll中)
exe和dll的区别在于exe中有Main函数入口,能够直接运行
需要使用哪个程序集就引用哪个程序集

4. 命名空间和类

二、C#与Java区别

1、文件名可以不和公共类名相同

java中文件名和公共类名需要相同

2. namespace 等同于 package

namespace之后需要用{}包含class

namespace packageA{
	class A{
		//...
	}
}

2. using 等同于import

using packageA; // 等同于import packageA.*
namespace packageB{
	class B{
		//...
	}
}

3.变量命名规则不同

C#以字母、下划线、@开头,后面为字母或数字或下划线,@只能用在开头
java以字母、下划线、$开头,后面为字母或数字或下划线或$

4. 关键字不同点

//C#中独有的关键字
as
base
bool //同java的boolean
checked
const//常量
decimal//小数类型的有效数字精度为28位
delegate// 委托类型
event
explicit
extern
fixed
implicit
in
internal// 同一程序集内可见
is
lock
namespace
object// 同JAVA的Object,但包括基本数据类型
operator
out
override
params
readonly
ref
sbyte// 8位无符号整数
sealed
sizeof
stackalloc
string//同java的String
struct
typeof
uint//32位无符号整数
ulong//64位无符号整数
unchecked
unsafe
ushort//16位无符号整数
using
virtual
// C#中独有的上下文关键字(仅在特定语言结构中充当关键字的标识符)
add
alias
ascending
descending
dynamic //动态类型,编译时不检查类型,运行时检查
from
get
global
group
into
join
let
orderby
partial
remove
select
set

5、Main函数首字母必须大写

using packageA; 
namespace packageB{
	class B{
		static void Mian(){
			//...
		}
	}
}

6、格式化字符串

1)替代标记{}

{0},{1},{...},数字为索引

using System; 
namespace packageB{
	class B{
		static void Mian(){
			Console.WriteLine("Number1 is {0},Number2 is {1}",1,2)
		}
	}
}

2)字符串插值$

using System; 
namespace packageB{
	class B{
		static void Mian(){
			int a = 1;
			int b = 2;
			Console.WriteLine($"Number1 is {a},Number2 is {b}")
		}
	}
}

3) 格式说明符

格式说明符语法

① 对齐说明符
可选,正数右对齐,负数左对齐,整数大小表示在多少个字符中对齐
② 格式字段

标准的格式字段

标准数字格式说明符

7、文档注释

C#使用///,java使用/** */

8、值类型和引用类型

C#中值类型和引用类型

9、访问修饰符

C#默认为private
java默认为default

10、var类型

从等号右边推断出的实际类型的速记
只能用于局部变量初始化,一旦编译器推断出变量的类型,它就是固定且不能更改的

namespace packageA{
	class A{
		static Main(){
			var a = 15;
			var classB = new B();
		}
	}
}

11、局部常量声明const

声明时必须初始化,且不能改变,可以为null,但不能为对象的引用

12、局部函数

可以在函数内再定义一个函数,然后使用它

13、引用参数ref

C#中值参数的传递与java中的参数传递相同,可以是变量也可以是表达式,值类型值传递,引用类型引用传递;
C#中引用参数,在声明时和使用时均需要ref修饰符,实参必须是变量,使用时形参的参数名将作为实参变量的别名,指向相同的内存位置

14、输出参数out

用于从方法体内将数据传出到调用代码

声明和调用需要使用修饰符out
实参必须为变量

与引用参数类似,指向相同的内存位置

与ref的不同点:在方法内部,需要给输出参数赋值之后才能读取它,也就是说没必要给实参赋值;

C#7.0开始,可以不必先声明一个变量作为out的实参,可以在方法调用时直接声明

namespace packageA{
	class A{
		static Main(){
			outParamMethod(out int a);
		}
	}
}

15、参数数组params

同java的...,允许零个或多个参数

需在数据类型前使用params修饰符修饰,在数据类型后用[]修饰

void test(params int[] vals){
    ...
}

//调用1
test(1,2,3);//方法会在堆中创建一个数组
//调用2
int[] intArr = {1,2,3};
test(intArr);//方法直接使用intArr数组

16、ref局部变量与ref返回

给一个变量取别名,无论值类型还是引用类型栈中都是同一位置

int y = 2;
ref int x = ref y;

ref局部变量通常与ref返回搭配使用

class A{
    private int a = 1;
    //ref返回,在返回类型前和return后声明,返回的是变量的引用
    public ref int test(){
        return ref a;
    }
}

class B{
    static void Main(){
        A cla = new A();
        ref int b = ref cla.test();
        //修改b的值会同时修改A类中a的值
    }
}

有如下限制: 1)ref返回类型不能为void 2)ref return 表达式不能为空值、常量、枚举成员、类或结构体的属性、指向只读位置的指针 3)ref return 表达式只能指向原先就在调用域内的位置或字段,不能指向方法的局部变量 4)ref局部变量只能被赋值一次,一旦被初始化不能修改 5)调用ref方法时,若没用ref关键字将返回值而非引用 6)将ref局部变量作为实参传递给其它方法时,其它方法只获取该变量的一个副本,也就是值传递

17、方法重载

方法的签名由方法名称、参数数目、参数数据类型和顺序和参数修饰符组成(返回类型不是)

18、命名参数

C#允许显式指定参数名字,以便于以任意顺序调用

class A{
    public int test(int a,int b){
        return a-b;
    }
    
    static void Main(){
        A cla = new A();
        int c = cla.test(b: 1,a:2);
        //一般的参数为位置参数,两者一起使用时,位置参数必须在前面
        int d = cla.test(3,b:2);
    }

}

19、可选参数

可选参数必须赋初始值,且在必填参数之后,params之前 并非所有参数类型都可作为可选参数 对于参数类型,只允许值参数类型;对于数据类型,值类型都可以,引用类型只有在默认值为null时可以