Fork me on GitHub

C基础快速入门C#

前言

本文主要面向有C基础的朋友快速掌握C#,对于C语言中已有的基础知识讲不再赘述,只简单介绍,重点在于不全面详细地标记出C#独有的特性,以便C基础的同学快速入门C#,由于C于C#差异大,还需要后续深入研究学习。
学习C#过程时写的程序

1. 变量

1. 基础类型变量

bool int uint char uchar string float double
C# 的变量类型可以有函数调用
float.Parse();
string.Count();
string.IndexOf(char x);
c# 可以自动吧int 类型直接转换为string 类型,但是一般不建议默认转换。

2. 非基础类型变量

类型转换

 y = (int)x;
int.Parse();
Convert.ToInt32();

2. 函数

万物皆为类,C#中不可以有像C++那样的全局函数,所以函数一定要用类进行封装。、
main函数是程序的入口,若不进行static 操作,意味着需要生成一个实例才可以操作main函数,与一般编程习惯相违背,所以main函数要用static 修饰。
static void main(string[]args);
通过string[]args形参代表接收命令行参数。

构造函数
构造函数无返回值(也没有void),直接用修饰符修饰(如public),区分构造函数的方法是通过其传入的形参的不同而确定。
构造函数里面可以在我们实例化类型时初始化类型里面的参数。

3. 命名空间

命名空间用于代替C语言中的头文件.h 命名空间所修饰的程序块,就是该命名空间的所有内容,用命名空间封装的类可以独立用一个文件,使用时和调用头文件一样

  • 命名空间namespace
  • 类型class
  • 函数/方法
    C#不需要头文件,所有程序都可以用.cs后缀名,使用时可以在文本开头使用using ManeSpaceXXX();
    同一个工程下的不同类可以用同一个命名空间

4. 程序结构

1. C和C#共有的结构以及差异

程序结构有顺序结构,循环结构,条件结构,这几种结构基本与C语言无差别。switch 结构有略微差别

  • switch 与C不同的是,C#在执行完对应case后不再继续执行

2. c#独有的结构

try
{
  //有可能报错的代码
}
catch
{
  //错误提示或处理,然后直接跳出try catch结构
}

循环结构
while、do while、for
foreach循环

5. 类

类在定义成员变量时可以不用赋初值,因为用new实例化时就已经自动赋初值。
类型与实例:类似代表某一同样的模板,实例代表不同的薄板下实际个体。
类型要用 new ClassName();实例化。
类中的函数调用所使用的本类变量,就是已实例化的成员变量,调用的哪个实例化的类的函数就用哪个实例的成员变量。

  1. private
    默认成员变量为private,不可被外部访问。在代码块中定义的类作用域只有在本代码块中。

  2. public

  3. static
    static 静态修饰的成员变量或方法,代表该成员变量属于类,而不是实例,得用类名调用,而且是唯一的,不能再自己实例化。
    在calss 中使用static 的场所一般是那些和本类成员变量无关紧要的操作,或者说是该类所有实例必不可少的共性。比如人类最高寿命,跑步所使用的物理引擎算法。

class stu
{
  public string name;
  public int age;
  public static string feature = "学生是被保护对象"
}
Console.WriteLine(stu.feature);

异常和错误处理

try
{
//有可能报错的代码
}
catch
{
//错误提示或处理,然后直接跳出try catch结构
}

3. 结构

字符串格式化

$"info = {a}"

关键字

  • raf(reference引用) :弱指针,用于函数参数向外传值,可代替函数对参数指针向外返回值。
    引用放栈里,对象放堆里。
    基本数据类型,在当前环境执行结束时销毁,而引用类型只有在引用的它的变量不存在时,会被垃圾回收机制回收。
    堆里的东西一旦没有被引用指向,就成垃圾,会被回收。
  • var 关键字能让编译器自行通过初始化的语句判断类型

面向对象,类,结构体,接口,继承

C#包装

命名空间(可理解为C语言添加的头文件,或者Python添加的库文件)

* System
Object

自定义类型

class

  • class 类型名
  • 类型存储大小由其成员变量确定
  • 实例(对象)创建方式 Human human = new Human();//Human()为构造函数
  • 访问级别:public private 默认是internal子类访问(同一程序内访问,方法的默认级别是private)
  • 类里面定义静态函数及其访问 类名.xx 包含在类中的静态函数、变量、常量要用类名调用,他们不属于某个对象,不能实例化。
  • 类里面定义静态变量及其访问 类名.xx
  • const常量的定义及其访问 类名.xx
  • 成员函数的定义及其访问 对象别名.xx
  • 使用静态函数来模拟成员函数
  • partial让类的定义放在多个地方
  • 属性Property看起来像变量的函数
  • 构造函数
    构造函数与普通函数相比无返回值,构造函数可以有多个,通过形参的不同来区分,可以有一个缺省构造函数。

.NET定义的类型

数组
C#数组与C语言的数组在定义和使用上有略微差异
定义数组
type[] arrayName;

list(动态数组):
list属于.NET平台开发的类,需要添加对应的命名空间using System.Collections.Generic;。并且当数据在操作时数据是保留状态,一旦数据结束操作,将被清空。非基础类型要用new开辟空间。
定义和初始化:List names = new List();
语法糖:list[index];
类型方法:
list.Add();
list.Count();

结构体

结构体和class的区别

  • 结构体是值类型,class 是引用类型(class 之间的赋值是传递地址,而不是值传递)
  • 在函数调用内部指令中,struct 直接在栈中进行内存分配,class是在堆中进行内存分配。
  • 栈中的内存,会在函数调用完成后回收,堆中的内存由C#运行时自动回收(GC)
  • 在函数调用过程中,class拷贝只是拷贝地址,struct 是所有数据都拷贝(深拷贝)
  • 如果需要将struct的引用传递给函数内部,则需要使用关键字ref
    函数传递结构体时,会在子函数内新建一个形参,在子函数内的改变和原参数没有关联;但类传递时传递的是地址,在子函数内操作类就是对实参操作;结构体若想像类一样被函数修改,在函数形参和调用时的实参都得加上ref 关键字。

继承

  • 概念:class B:A{} 类型B继承自类型A
  • A 叫做父类(基类),B叫做子类
  • B继承了A中的属性和方法
  • override 给个机会给子类去实现,子类可以重装载父类的函数,实现同样的函数名但是不一样的函数内容,子类函数声明用override 父类函数声明加virtual
  • protected 有继承的子类能访问,外面不能访问
  • struct 默认继承自object,class如果没有明确指出继承自某个类型,那么其默认继承自object
  • interface:声明我是一个什么样子的类型,不实现。
public interface IUpdate{
    void Update();//只能是public
}
public interface IAwake{
    void Awake();//只能是public
}
public interface ILifeCycly : IUpdate,IAwke//继承了两个接口
{
}

  • struct不能继承struct或者class,但可以继承接口、
  • class只能继承一个或零个基类,但能继承任意多个接口
  • abstrauct:不能实例化,可以暂时不实现接口、函数,等子类的实现
  • 父类变量 可以存储子类的变量(地址),但不能反过来
  • 潜在意思,因为子类B是一个父类A
  • 比如A是Human B是teacher 老师是人但人不一定是老师
    由于子类包含了父类的实现,所以子类实例可以赋值给父类变量
  • 所有类型的基类是System.Object ToString()函数可以重写

泛型(C++为模板)
定义:
public class sense{
public Data HData;
public Data LData;
public void GetSense(Data HData,Data LData){
this.HData = HData;
this.LData = LData;
}
}
GetSense gis = new GetSense(0,1);
GetSense gfs = new GetSense(0,1.5f);
GetSense gfs = new GetSense("0","1.5f");

目的:若代码几乎一样,只有成员变量类型不一样时可以简化代码,减少代码量。

与C++不同,C++可以继承多个父类

命名空间namespace

命名空间定义在某一头文件中
在函数中声明了命名空间的名称,只对该函数有效。用法同局部变量和全局变量。
使用命名空间里的名称
法一
using namespace std;//声明命名空间
cout << "helloword";
法二
std::cout << "helloword" //避免完全暴露名称以及命名冲突
法三
using std::cout;//只使用个别命名空间里面的名称,其他的都不会暴露
using std::cin;
using std::endl;
cout << "helloword";

成员函数内可以用this.代替对应的对象访问自己成员的变量。

使用杂谈

索引器
get set =>

类库.dll

类库.dll文件就是包装好的程序库,可供主程序调用。减少重复代码的编写,也可通过添加现有的.dll库文件,从而减少工作量。

1. 新建类库工程

若在现有工程中想创建本工程使用的类库,可直接在解决方案资源管理器->右键该解决方案->添加->新建项目->选择类库(.NET Framework)。该工程会自动在bin/debug中生成.dll文件。
注意选错输出文件会导致.dll调用失败

2. 访问权限

.dll的访问只能被访问有public修饰的类,以及该类中被public修饰的成员变量或者函数。

3. 使用.dll类库

  1. 添加.dll文件:在解决方案资源管理器->右键该项目名称->添加引用->项目(同个项目下)
  2. 在需要调用的程序文本开头添加相应的命名空间。

4. .dll平台介绍

该平台为微软开发的平台,可供创作者上传.dll文件,使用者只需要在该平台下载即可。
具体操作:工具->NuGet包管理器->管理解决方案的NuGet程序包

1. 新建一个项目

根据类型设置不同文件。在解决方案资源管理器中右键对应项目属性可以设置修改输出文件类型。

文件介绍

.sln 解决方案文件;
.csproj 项目文件;
.cs CSharp 源文件;
.pdb文件为调试文件
项目就是一个个小的执行文件,解决方案就是大型的项目集合,一个解决方案可以有很多个项目.sln是解决方案管理文件后缀名。

  • 在一个解决方案中新建第二个项目,右边资源管理器右键新建项目。
  • 将项目设置为启动项,启动项在右边窗口为黑色加粗。
  • 解决方案资源管理器->右键项目->重新生成 就是重新编译然后生成对应文件。
  • VS 中,用alt + 鼠标拖动可每行同位置插入。

3. C#的命名规则

变量名用小驼峰,函数名用大驼峰。
小驼峰首字母小写,其后每个单词首字母大写。
大驼峰首字母大写,其后每个单词首字母也大写。

posted @ 2023-05-12 16:09  赤诚Xie  阅读(9)  评论(0编辑  收藏  举报