[C#] 基础笔记

1.0 -VS中调试方法

F11-逐语句调试

F12-逐过程调试

断点调试-程序运行到那里会终止(鼠标左键点击代码左边灰色地带),然后点F11一步一步执行,就是不用一步一步点前面,从断点那里开始调试

 

2.0-for循环

1-已知循环次数时候可以使用for循环

2-输入完for后点击两次Tab创建for循环框架,输入for然后点击两次Tab创建倒序for循环

 

3.0-随机数Random

Random r = new Random(); 
int rnumber = r.Next(1, 2);

 

4.0-变量和字段和常量

字段都是引用在结构里面,命名规范,前面加下划线,比如:_red;

同个字段可以多次赋值引用,同个变量只可以一次引用

注意:null和""表示的不一样,null并没有开发内存空间,而""有;

常量的命名规范:

const int number=10;

常量不可重新赋值

变量的作用域是两个大括号中间

变量和字段只能在初始化时候赋值,要赋值只能在方法体或者构造函数里面里面

 

 

5.0-数组的基本命名规范

int[] nums=new int[9]; 
int[] num ={1,2,3,4,5,6,7,8,9};
int[] c= new int[] { 1, 2, 3, 4, 5, 6 };

数组升序排列方法:Array.Sort(中间输入要排列的int数值);

数组反正排列方法:Array.Reverse();

数组里面参数反转方法:

for(int i=0; i<nums.Length/2;i++) 
{ string a=nums[i]; 
nums[i]=nums[nums.Length-1-i];
 nums[nums.Length-1-i]=a; }

 

 

6.0-枚举命名规范

public enum Gender { man, woman }

字符串转枚举类型:

string a="男"; 
Gender b=(Gender)Enum.Parse(typeof(Gender),a);

 

7.0-结构的命名规范

public struct Person { 

public string _name;

public int _age;

public Gender _gender; }

结构里面装的都是字段

结构的调用方法:

Person zbPerson; 

zbPerson._name="XX";

 

8.0-常见的程序判断

判断闰年:

(year%400==0)||(year%4 == 0 && year%100 != 0)

 

9.0-常用的强制变量转换

Convert.Toint32(); 

int.Parse(); 

bool b=int.TryParse("要转化的目标",out number);

 

10.0-函数方法的注意事项

函数的功能一定要单一,一个函数实现一个功能;

在控制台程序中,方法中最忌讳的就是出现提示用户输入的字眼;

out参数:可以在一个方法中返回多种不同类型的值;在使用out参数以后,必须在函数内部对进行返回的变量赋值;

ref参数:能够将一个变量以参数的形式带入一个方法中改变数值,并且返回新数值,ref函数要求在方法外为其赋值,在方法内不需要;

例:

TestTwo(ref number); 

 public static void TestTwo( ref int n ) { 

n+=10; 

}

 

params可变参数:将实参列表中跟可变参数数组类型一致的元素都当作数组的元素去处理。

params可变参数必须是形参列表中的最后一个元素

方法的重载:

public static void Getmax(int a,int b) { } 

public staic void Getmax(string a,string b) { }

上面构成重载,其他条件:类型不一样,或者类型一样,变量的数量不一样;

方法的递归:

方法自己调用自己(遍历一个文件夹中的所有文件)

public staic TellStory() {

Console.Write(1); 

Console.Write(2); 

Console.Write(3); 

TellStory(); 

}

 

 

11.0-数值取两位小数的方法

1. double d=3.145; 

   d.Tostring("0.00"); 

2. Console.WriteLine("{0:0.00}",d);

 

12.0-switch case循环基本结构

做多条件的定值判断

switch(变量或者表达式的值)

{ case1:xxx;break case2: case3: default:(表示剩余其他条件) }

程序执行到switch处,首先将括号中的变量或者表达式的值计算出来,然后拿着这个值依次到每个case后面的所带的值进行匹配,匹配成功就执行。都不成功就执行default语句

 

 

 

13.0- if else循环

注意else永远与离它最近的if配对,所以有多条件if时候,最后加个else一般都会触发else

 

 

14.0-if else-if循环

做多条件的区间判断

if(条件) { } else if(条件) { } else if(条件) { } else { }

首先判断if里面的条件是否成立,如果成立就执行if语句后面大括号的内容,执行完立刻跳出if else-if循环 ; 如果不成立,就继续往下判断else if里面的条件,如果成立就执行跳出,出执行就继续往下遍历else if里面的条件是否满足然后判断是否执行,如果所有条件都不满足,就执行else里面的。

 

多个if是所有的if都会进行判断

if else if是只要有满足条件的,就不再对之后的else if进行判断

 

 

15.0终止操作的几个行数

break:跳出switch- case结构

可以跳出当前循环,继续执行当前循环外下面的函数

return:跳出这个方法,函数

continue:立即结束本次循环,回到循环条件,判断条件是否成立,然后接着开始循环

 

 

16.0面向对象总结

语法:

 

public class 类名 { 

字段;

属性;

方法; }

 

 

类的实例化

Person zsPerson=new Person();

this:表示当前这个类的对象;

类是不占内存的,而对象占内存

类的初始化

给类的对象每个属性去赋值

 

 

属性的作用:保护字段,对字段的赋值和取值进行限定

属性的本质就是两个方法:

get()和set()

比如:

get{ return _name; } set{ _name=value; }

 

Field 字段;

Method 方法;

Property 属性;

 

访问修饰符:

public 公开的,在哪里都能访问到;

private 私有的,只能在当前类的内部访问,出了这个类就访问不到。

protected:可以在当前类的内部以及该类的子类中访问,该类实例化出来的对象也访问不了

internal:只能在当前项目中访问,同项目中,internal和public权限一样

protected internal:

protected+internal

1)能够修饰类的访问修饰符只有两个:public,internal。

2)可访问性不一致。

子类的访问权限不能高于父类的访问权限,会暴漏父类的成员。

 

 

静态和非静态的区别:(static关键字)

1.在非静态类中,既可以有实例成员,也可以有静态成员

2.在调用实例成员时候,需要使用对象名.实例成员。

Person a=new Person();

a.playGame();

在调用静态成员时候,需要使用类名.静态成员名

Person.closeGame();

静态成员必须使用类名去调用,实例成员使用对象名去调用

3.静态函数中,只用访问静态成员,不允许访问实例成员

实例函数中,可以访问静态加实例成员

静态类中,只允许有静态成员,不允许出现实例成员

 

用法:

1.0如果你想要一个类作为"工具类"去使用,可以把类写成静态的,比如 :Console类

2.0 静态类在整个项目中资源共享

只有在程序全部结束之后,静态类才会释放资源;调用GC Garbage Collection垃圾回收器

 

 

 

构造函数

作用:帮助我们初始化对象(给对象的每个属性依次的赋值)

给实例成员创建对象时候,首先会执行构造函数

构造函数是一个特殊的方法;

1.构造函数没有返回值,连void都不能写;

2.构造函数的名称必须跟类名一样。

3.构造函数可以有重载,就是名字一样,参数不同

4. 类中会有一个默认的无参数的构造函数,如果你写了一个新的构造函数,不管是无参有参,默认的都会被替代

想要在创建对象时候把参数创进去,就写一个构造函数。

 

 

new关键字

Person zsPerson=new Person();

new帮助我们做了三件事儿;

1.在内存中开辟一块地方;

2.在开辟的空间中创建对象

3.调用对象的构造函数进行初始化对象

3.隐藏父类的成员

 

this关键字

1.代表当前类的对象,在输出属性时候在前面加this,是为了区分开属性和局部变量

2.在类当中显示的调用本类的构造函数,在构造函数后面加 :this() 里面填选要调用的构造函数的参数,不需要调用的参数填写0

 

 

析构函数

当程序结束的时候,析构函数才执行

帮助我们释放资源

 

 

17.0命名空间

可以认为类是属于命名空间的;

如果当前项目没有我们使用的类的命名空间,需要我们手动导入这个类的命名空间;

1)用鼠标去点击。

2)alt+shiift+F10;

 

2. 在一个项目中引用另一个项目的类

1)在工具栏添加引用

2)引用命名空间

 

18.0值类型和引用类型

区别:

1)值类型和引用类型在内存上储存的地方不一样。

2)在传递值类型和传递应用类型的时候,传递的方式不一样。

值类型我们称之为值传递,引用类型我们称之为引用传递。

我们学的值类型和引用类型:

数据类型

值类型:int(整数), double(小数),bool(布尔),char(字符),decimal(金钱),struct(结构),enum(枚举);

1)整数类型: int 只能存储整数,不能存储小数。

2)小数类型: double 既能存储整数,也能存储小数,小数点后面的位数15~16位

3)金钱类型:decimal 用来存储金钱,值后面需要加上一个m。

4)字符串类型: string,用来存储多个文本,也可以存储空,字符串类型的值要用""引用。

5)字符类型: char,用来存储单个字符,最多,最少只能有一个字符,不能存储空。

字符类型的值需要用单引号' '引用。

变量命名规范:

1)Camel 骆驼命名规范。要求变量名首单词的首单词要小写,其余每个单词的首字母都要大写,多用于给变量命名。

例:highSchoolStudent

2)Pascal 命名规范。 每个单词的首字母都要大写,多用于给类和方法命名。

例:HighSchoolStudent

 

引用类型:string,自定义类,数组,object

储存:

值类型的值是储存在内存的栈当中。

引用类型的值是储存在内存的堆中。

 

 

19.0字符串

1)字符串的不可变性

当你给一个字符串重新赋值之后,老值并没有销毁,而是重新开辟了一块空间储存新值。

 

字符串可以看成一个只读的char类型的数组;

 

当程序结束后,GC扫描整个内存,如果发现有的空间没有被指向,则立即把它销毁

字符串提供的方法

1)Length:获得当前字符串中字符的个数

2)ToUpper():将字符转换成大写形式

3)ToLower():将字符串转换成小写形式;

4)Equals(lessonTwo,stringComparison.OrdinalIgnoreCase):比较两个字符串,可以忽略大小写;

5)Split():分割字符串,返回字符串类型的数组。

例:切除字符串里面的月字

Split(new char[]{'月 '},StringSplitOptions.RemoveEmptyEntries);

6)Substring():解决字符串。在截取的时候包含要截取的那个位置。

7)IndexOf():判断某个字符串在字符串中第一次出现的位置,如果没有返回-1,

8)LastIndexOf():判断某个字符串在字符串中最后一次出现的位置,如果没有返回-1

9)StartsWith():判断以....开始

10)EndsWith():判断以....结束

11)Replace():将字符串中某个字符串替换成一个新的字符串

12)Contains():判断某个字符串是否包含指定的字符串

13)Trim():去掉字符串中前后的空格

14)TrimEnd():去掉字符串中结尾的空格

15)TrimStart():去掉字符串中前面的空格

16)string.IsNullOrEmpty():判断一个字符串是否为空或者为null

17)string.Join():将数组按照指定的字符串连接,返回一个字符串

18)ToCharArray() 转化成char类型的数组

 

 

20.0继承

我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,

单独的封装到一个类中,作为这些类的父类。

Student,Teacher,Driver 子类 派生类

Person 父类 基类

子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段

子类并没有继承父类的构造函数,但是。子类会默认的调用父类无参数的构造函数,

创建父类对象,让子类可以使用父类中的成员。

 

所以,如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,

子类调用不到,所以子类会报错。

解决办法:

1)重新写一个无参数的构造函数

2)使用关键字base调用有参的构造函数

 

子类对象可以调用父类对象的成员,但是父类对象永远只能调用父类对象的成员

 

在C#当中,所有类都直接或者间接的继承了object类

 

 

继承的特性

1)单根性:一个子类只能有一个父类

2)传递性(祖宗的迟早都是我的)

 

 

21.0里氏转换

1)子类可以赋值给父类:如果有一个地方需要父类做参数,可以给一个子类代替父类

2)如果父类中装的是子类对象,可以将父类转换成子类对象

Person p=new Student(); 

Student ss=(Student)p;

3)判断父类是否能转换成子类对象的判断

is:表示类型转换,如果能够转换成功,返回true,转换失败返回false

语法:

if(p is Teacher) { }

as:如果能够转换则返回对应的对象,否则返回一个null

语法:

Teacher t =p as Teacher;

 

 

22.0集合

 

ArrayList集合

命名:

ArrayList list=new ArrayList();

每次集合中实际包含的元素个数(count)超过了可以包含的元素的个数(capcity)的时候,

集合就会向内存中申请多开辟一倍的空间,来保证集合的长度一直够用。

 

 

方法:

1)添加单个元素:

list.Add();

2)添加集合元素:

list.AddRange(list);

3)清空所有元素:

list.Clear();

4)删除单个元素,写谁就删谁

list.Remove(true);

5)根据下标删除元素

list.RemoveAt(0);

6)根据下表去移除一定范围的元素

list.RemoveRange(0,3);

7)升序排列

list.Sort();

8)反转

list.Reverse();

9)在指定的位置插入一个元素

list.Insert(1,"插入的");

10)在指定的位置插入一个集合

list.InsertRange(0,new string[]{"狗莹”,"二莹"});

11)判断是否包含某个指定的元素

bool b=list.Contains(1);

 

Hashtable 键值对集合

在键值对集合中,我们是根据键去找值的

键值对对象{键}=值;

*****:键值对集合当中,键必须是唯一的,而值是可以重复的。

举例:

Hashtable ht=new Hashtable();

ht.Add(1,"张三");

ht.Add(2,"李四");

ht.Add(3,"张三");

ht.Add(false,"错误的");

ht[4]="添加的"; 这也是添加数据的方法

 

遍历输出的语法:

foreach(var item in ht.Keys) { 

Console.WriteLine(item) ;

}

键值对集合方法

ht.Clear();清空

ht.Remove();移除某个数据

ht.Contains();判断时候包含

 

 

List泛型集合

声明:List <int> list=new List<int>();

基本方法和ArrayList一样

不过List集合可以转化成数组:

int[] nums=list.ToArray() 注意:转化成什么类型数组要取决于什么类型集合

数组也可以转化成集合:

list<int> listTwo=nums.ToList();

 

遍历输出

foreach(var item in list) { 

}

 

字典集合(不用拆装箱,比ArrayList集合的好处)

声明:

Dictionary<int,string> dic=new Dictionary<int,string>();

和Hashtable集合用法一样,不过就是限制键与值的类型,而且有新的遍历方法:

foreach(KeyValuePair<int,string> kv in dic)

{

Console.WriteLine("{0}----{1}",kv.Key,kv.Value);

}

 

 

 

23.0 Path类

专门用来操作路径的类

 

操作方法

1)获得文件名

Path.GetFileName();

2)获得文件名但是不包括扩展名

Path.GetFileNameWithoutExtension();

3)获得文件的扩展名

Path.GetExtension();

4)获得文件所在的文件夹的名称

Path.GetDirectoryName();

5)获得文件所在的全路径

Path.GetFullPath()

6)连接两个字符串作为路径

Path.Combine(@"c:\a\","b.txt")

 

 

24.0 File类(操作小文件)

操作方法

1)创建一个文件

File.Create(这里填写路径);

2)删除一个文件

File.Delete(文件路径);

3)复制一个文件

File.Copy(复制文件路径,新文件的路径 );

4)剪切一个文件

File.Move(文件路径);

5)读数据

File.ReadAllBytes();

读取完得到的是一个字节数组,需要转换成字符串:

Encoding.Default.GetString(字节数组);

其他编码各式:

UTF-8 GB2312 GBK ASCII Unicode

用其他编码读取:

Encoding.GetEncoding("GB2312").GetString(字节数组);

 

 

6)写数据

File.WriteAllBytes();

写入之前,需要把字符串转化成字节数组:

Encoding.Default.GetBytes(字符串);

之前有的话会覆盖掉

追加方法:

File.AppendAllText("路径","要追加的文本");

 

文件的位置路径:

绝对路径和相对路径

绝对路径:通过给定的这个路径我能在我的电脑中找到这个文件

相对路径:可执行的文件的路径

将文件放在相对路径下面时候,可以直接读取访问

 

用File类读取文件是一下子全部读取过来,会给程序造成压力;

 

 

25.0 编码

乱码:

产生乱码的原因:就是你保存的这个文件所采用的编码,跟你打开这个文件所采用的编码格式不一样。

 

 

26.0 检测函数运行时间方法

Stopwatch sw=new Stopwatch();
 sw.Start();
 ... ... 这里是你要检测的函数 ...
 se.Stop(); 
Console.WriteLine(sw.Elapsed);

 

 

27.0 装箱和拆箱

装箱:值类型转化成引用类型

拆箱:引用类型转化成值类型

int n=10;
object o=n;      装箱 
int nn=(int)0;   拆箱

 

判断条件:看两种类型是否发生了装箱或者拆箱,要看,这两种类型是否存在继承关系。

程序中,应该尽量避免装箱和拆箱操作,不然会加长程序执行的时间。

 

 

28.0文件流(操作大文件)

声明:FileStream fsRead=new FileStream("文件路径",FileMode.OpenOrCreate(针对文件进行的操作),FileAccess.Read(针对文件里面的数据的操作));

关闭流:fsRead.Close();

释放流所占用的资源:fsRead.Dispose();

 

将创建文件流对象的过程写在using当中,会自动地帮助我们释放流所占用的资源。

using(FileStream fsread = new FileStream(@"C:\Users\DFDF\Desktop\新建文本文档.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)) {
 string s="abc";
 byte[] buffer=Encoding.UTF8.GetBytes(s);
 fsWrite.Write(buffer,0,buffer.Lengeh);
 }

 

读取文件并且写入输出

using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite)) {
 byte[] buffer = new byte[1024 * 1024 * 5];
 int r = fsRead.Read(buffer, 0, buffer.Length);
 textBox1.Text = Encoding.Default.GetString(buffer, 0, r);
 }

想要追加写入时候,可以使用FileMode.Append

 

 

使用StramReader和SteamWriter

using(StreamReader sr =new StreamReader("路径")) {
 sr.ReadLine();  
 //sr.EndOfStrea--判断是否读取到这个文件的结尾
 }

 

steamWriter使用方法同理

 

 

 

 

29.0多态

实现多态的方法:

1)虚方法(父类的函数有用时候):

1.将父类的方法标记为虚方法,关键字:virtual,这个函数可以被子类重新写一遍,在子类的方法前面加上override

2)抽象类(父类的函数没有用的时候):

当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将方法写成抽象方法

父对象关键字:abstract

子对象:override

抽象类的方法不能有方法体,例子:

public abstract void Bark();

 

 

抽象类笔记:

1.抽象成员必须标记为abstract,并且不能有任何实现。

2.抽象成员必须在抽象类中。

3.抽象类不能被实例化

4.子类继承抽象类后,必须把父类中的所有抽象成员都重写。

(除非子类也是一个抽象类,则可以不重写)

5.抽象成员的访问修饰符不能是private

6.在抽象类中可以包含实例成员,并且抽象类的实例成员可以不被子类实现。

7.抽象类是有构造函数的。虽然不能被实例化。

8.子类的抽象方法的签名必须和父类抽象方法的签名一致。

(签名:返回值和参数);

 

 

3)接口

语法:

[public] interface I..able { 成员; }

1)接口里面不允许添加访问修饰符,默认就是public

2)不允许写具有方法体的函数,构造函数

3)接口中可以写属性,方法。属性,索引器,事件

4)只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员

5)为了多态。接口不能被实例化

6)接口与接口之间可以继承,并且可以多继承

7) 接口并不能去继承一个类,而类可以继承接口

显示实现接口(解决接口中的方法和类的方法同名问题)

public class Bird:IFlyable { 
public void Fly() { } 
void IFlyable.Fly() { }
 } 
public interface IFlyable {
 void Fly();
 }

 

 

 

30.0值传递和引用传递

1)值类型在复制的时候,传递的是这个值的本身。

2)引用类型在复制的时候,传递的是这个对象的引用。

改变一个,另外的值就跟着改变。

注意:因为字符串的不可变性,所以都是字符串类型赋值的话不会受到影响

用了ref函数后,会在栈中复制一份地址给新值,一起改变

 

 

31.0序列化和反序列化

序列化:就是将对象转化为二进制

反序列化:就是将二进制转化为对象

作用:传输数据,网络传输的数据都是二进制

步骤:

1)首先先将要被序列化的类标记为可序列化

关键字 [Serializable]

2)然后,引用文件流

3)引用序列化的类

关键字:BinaryFormatter 要引用相关的命名空间

BinaryFormatter bf=new BinaryFormatter();
 bf.Serialize(文件流的对象,要序列化的对象);

4)读取文件

用反序列化方法

bf.DeSerialize(文件流)

 

 

32.0部分类

如果在一个项目中,想对同一个类进行多次编程,就可以用到部分类

public partial class Person { } public partial class Person { }

 

33.0密封类

关键字sealed

不能够被其他类继承,但是可以继承于其他类。

 

 

34.0自动属性和普通属性

自动属性没有方法体,写的时候也不用先定义私有字段,不过在本质上也会自动生成一个私有字段。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值