C#:程序员快速熟悉C#

Posted tiny_ten

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#:程序员快速熟悉C#相关的知识,希望对你有一定的参考价值。

C#:程序员快速熟悉C#

前言

我此前有2年+的python工作经验(游戏行业),后来技术栈换成了unity,用的C#+lua。lua是比较好上手的,毕竟也是脚本。不过C#自己还是不太熟悉,虽然C++都是学过,C#上学的时候也学过,哈哈都忘了,还是想花点时间熟悉一下C#,增加一点自己看C#代码的自信。

所以,如果你是一个脚本语言比较熟悉的程序,本文十分适合你,只要你是一个熟练老手,或者是已经掌握了那么1、2种编程语言看这篇文章熟悉C#再适合不过了。不过即使你是一个刚刚开始学习编程语言的小白,本文展示的也是那些C#中比较特别或者其他语言也有,但是C#中叫法不同的一些点。(如果本文看不懂,可能需要去补C++基础。)
c#参考
菜鸟教程
微软官方文档

基础篇

说的一门高级语言的基础,也就是变量、运算符、结构体、函数、类那些事。需要强调的如下:

变量命名

和C++类似

  • 可以用 下划线_ 以及 字母 开头命名变量
  • 大小写敏感
  • 可以包含_,字母,数字
  • 不能用保留字

但是C#可以使用@开头,并且命名里其他位置也可以有@

字符串常量 @“”

c# 中字符串之前加@ 可以使得字符串按照原格式,并且无需对特殊字符转义。
比如@“a\\bbb”, 打印就是“a\\bbb”,不用在\\前面加转义。

数组

初始化数组的方式:

int[] balance = new int[10];
int[] balance = 1,2,3;
int[] balance = new int[3]1,2,3;//3可以省略

c#里多维数组不同于c++,可以认为c++里的多维数组等同于数组的数组,而c#对两者进行了区分,c#中数组的数组被称为交错数组。多维数组以及交错数组的的声明、初始化,使用如下:

// 多维数组
int [3,4] names; //声明
int [,] names = new int [3,4] // 初始化以及赋值
	0,1,2,3,
	4,5,6,7,
	8,9,10,11;
int val  = names[2,3]//访问 val值是11

// 交错数组
int [][] scores;// 声明
int[][] scores = new int[2][]new int[]92,93,94,new int[]85,66,87,88;//初始化(可以不赋值)
int val = scores[1][1]//访问 val值是66

参数数组

用params修饰 表示未知数量的参数,类似python的**kwargs, 传参时候可以传数组实参,也可以传一组数组元素。 代码如下:

public int AddElements(params int[] arr)
     int sum = 0;
     foreach (int i in arr)
        sum += i;
     
     return sum;
  
int []p = new int []1, 2, 3, 4, 5;
int sum = app.AddElements(p); //传数组实参
int sum = app.AddElements(1, 2, 3, 4, 5);// 传一组数组元素 sum的结果都是15

数组的基类 Array

详见C# Array 类
常用的属性如 Length,方法如Sort()等

int []add = new int[]3,4,5;
if (add is Array)
    Console.WriteLine("true"); // 会打印

结构体

循环

foreach 类似于python for a in list 或者lua中 for i,v in ipairs(table)

int []n = new int[10]; // int [] n之间的空格随意 都可以省略或者省略其中1个,也可以都不省略
foreach (int j in n )


结构 struct

和c++一样,c#的struct也是值类型。简单来说,可以认为是轻量的类(类是引用类型),不支持继承、不支持重写默认构造函数。具体参考这里

枚举

enum Days  Sun, Mon, tue, Wed, thu, Fri, Sat ;
Days a = Days.Sun;

函数传参方式修饰符

C#里有 ref 以及 out这两个传参方式修饰符
C#中有三种参数传递方式:

  1. 值传参:实参和形参有不同的内存空间,函数内对参数的值进行更改,不会影响函数外实参的值。
  2. 引用传参:实参和形参有相同的内存空间,改形参的值等于改实参的值,实参需要初始化。ref修饰。
  3. 输出传参:相当于引用传递,但是实参可以不初始化,仅声明即可。out修饰。

ref的使用如下段代码所示:

void fun(ref int param) // 函数声明
	param = 100;

int a = 10;
fun(ref a); // 函数调用, a的值会变成100

访问修饰符

默认是private, 除了private,还有public、protected、internal、protected internal一共5种访问修饰符。
引用网友的总结
比如说:一个人A为父类,他的儿子B,妻子C,私生子D(注:D不在他家里)
如果我们给A的事情增加修饰符:
public事件,地球人都知道,全公开
protected事件,A,B,D知道(A和他的所有儿子知道,妻子C不知道)
private事件,只有A知道(隐私?心事?)
internal事件,A,B,C知道(A家里人都知道,私生子D不知道)
protected internal事件,A,B,C,D都知道,其它人不知道

运算符重载

类似c++,这里简单举个代码的例子。例子参考菜鸟教程。主要是opreator关键字,有些运算符可以重载,有些不可以。

 public static Box operator+ (Box b, Box c)
     Box box = new Box();
     box.length = b.length + c.length;
     box.breadth = b.breadth + c.breadth;
     box.height = b.height + c.height;
     return box;
  

命名空间

namespace以及using这两个关键字。参考菜鸟教程

类的默认访问标识是internal,成员的默认访问标识是private。类基本和c++类似,都有构造函数、析构函数、成员初始化列表等,不过c#不支持多继承,只支持单继承,c++支持多继承,不过c#可以用接口来实现和多重继承等同的效果。
下面代码涵盖了c#类相关的一些基本内容,注释给出了进一步的描述。

基础

using System;
class Animal
    static public int count = 0; // 定义静态变量
    void countAdd()// 定义静态方法,静态成员只能静态方法访问
        count += 1;
    
    //这是重写无参构造函数,不重写会有默认构造函数
    protected Animal()// 访问修饰符不能是private,按需是protected、public或者internal
        countAdd();
         Console.WriteLine("Create Animal!");
    

    protected Animal(string name)
        countAdd();
         Console.WriteLine("Create Animal with name 0!", name);
    

    ~Animal() //不能继承、重载(函数名相同,函数签名不同,是静态多态性的一种)
        Console.WriteLine("Delete Animal!");
    


// 这是接口,接口只声明方法,不实现
interface Friend 
    public void playWithPeople();

class Cat:Animal //冒号表示继承
    public Cat()
         Console.WriteLine("Create Cat!");
    

    public Cat(string name):base(name) // 这里用到了成员初始化列表,另一个关键字this表示自己
         Console.WriteLine("Create Cat with name 0!", name);
    

     ~Cat() //不能继承、重载(函数名相同,函数签名不同)
        Console.WriteLine("Delete Cat!");
    


 class Dog:Animal,Friend
    public Dog()
         Console.WriteLine("Create Dog!");
    

    public Dog(string name)this()
         Console.WriteLine("Create Dog with name 0!", name);
    

	// 继承了接口,这里必须实现,否则编译不通过
    public void playWithPeople()
         Console.WriteLine("This dog is playing with people!");
    


class HelloWorld
	static void Main(string[] args)
           Cat cat = new Cat("catty");
           Dog dog = new Dog("doggy");
           Console.WriteLine(Animal.count);
           Console.WriteLine(Cat.count);
           Console.WriteLine(Dog.count);
           dog.playWithPeople();
	

运行程序最后输出的是

Create Animal with name catty!
Create Cat with name catty!
Create Animal!
Create Dog!
Create Dog with name doggy!
2
2
2
This dog is playing with people!

多态

和c++类似
抽象类可以定义抽象方法,用abstract修饰抽象类,涉及多态以及方法重写的几个关键字:abstract、vritual、new、override

  • abstract可以修饰类,可以修饰方法。抽象方法必须声明在抽象类中,抽象方法不能有实现,必须被子类实现,子类方法之前必须有override。
  • vritual 修饰方法,抽象类和虚方法就可以实现多态,虚方法可以有实现,也可以被子类实现。
  • new 覆盖基类方法, 子类(与父类)同名方法 默认的修饰,可以隐藏父类的abstract or vritual方法,也可以是普通方法,甚至没有声明的方法(不过对于没有声明的方法不会跑错,会有warning)。不实现多态,声明的什么类型就调用什么类型的方法。
  • override 重写,重写父类的方法,父类的方法可以是抽象方法或者虚方法(只能是二者之一),重写会实现多态:即调用实例真正类型的方法。

关于 new和override的区别 例子如下

Animal catA = new Cat();
catA.speak();
catA.run();

比如Cat类继承Animal类,Animal定义两个虚方法,speak以及run,Cat重写了这两个方法,用override修饰speak,用new修饰run,上面的代码 speak调用的是Cat类的实现,而run调用的是Animal的实现。

预处理

菜鸟教程里表示c#里好像没有宏定义,c++里是有的,这里我先不深究,不过c#里也有类似宏定义的功能,就是#define,可以直接看菜鸟教程,之后我可能会补充。
关于宏定义的利弊,可以参考知乎上 皮皮关的回答

异常处理

一场处理常见的那几种语言都差不多,c#和java一样,比c++多一个关键字 finally,另外三个关键字就是try,catch, throw。

  • try 后面跟一段可能抛出异常的代码
  • catch后面跟异常处理代码
  • finally后面跟不管有没有异常都要执行的代码,比如打开文件之后,不论有没有异常 文件都要关闭
  • throw用于主动抛出异常

可以自定义异常,继承 System.ApplicationException 即可。

文件读写

直接看菜鸟教程:文件的输入与输出吧,哈哈。

高级篇

属性(properties)

参考官方文档
c#中的属性特指通过get or set 访问器(accessors)读写的数据域(field),有点类似于python的@property以及@name.setter(python里不定义setter就是一个只读属性),python声明访问器的方式比较简单,就是一个装饰器@property(等于c#中的get),c#定义访问器的语法会稍微显得正式(复杂)一些,如下:

class Student
	private string code = "sq";
	public string Code
		get
			return code;
		
		set
			code = value;
		
	
 

//下面写Main函数中
Student s = new Student();
s.Code = "hahaha";
Console.WriteLine(s.Code);//结果是hahaha

另外,C#的访问器可以使用简化版,其中= "instial string"是初始化语法,非必须,按需要使用,get,set至少有其中一个即可;

public string Codeget;set; = "instial string";

当 get以及set的主体只有一个表达式的时候,还可以简化如下:

class Student
	private string code = "sq";
	public string Code
		get => code;
		set => code = value;
	
 

特性

参考官方文档

创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

以上是关于C#:程序员快速熟悉C#的主要内容,如果未能解决你的问题,请参考以下文章

C#:程序员快速熟悉C#

程序员带你学习安卓开发,十天快速入-对比C#学习java语法

(39)C#中使用JSON库

(39)C#中使用JSON库

C# 泛型简介

c# ?和?? 用法