C#易忘笔记
基本语法
-
数组命名
int [] char = {1,2,3}; int [] char = new int[10];
-
冒泡循环
for(int i=0; i<num.length-1; i++) { for(int j=0; j<num.length-i-1; j++) { if(num[j]<num[j+1]) { int temp; temp=num[j]; num[j]=num[j+1]; num[j+1]=temp; } } }
-
占位符
占位符最终按照填坑的顺序输出
Console.WriteLine("爱{0}",name);
. -
转义符
- +":表示一个英文半角的双引号。\表示转义,而不表示字符。
- \r\n:表示换行,操作系统支持
- \n:表示换行,操作系统不支持
- \b:表示一个退格键,\b放到字符串的两边没有效果
- \t:表示一个tab键
- \:表示一个\
-
用户输入
string name = Console.ReadLine();
-
类型转换
强制类型转换显示类型转换 结果:丢失精度
int result = (int)303.6;
string str = “12.34”;
double d = Convert.ToDouble(str); -
异常捕获处理
try{}catch{}
-
枚举
语法:
[public] enum 枚举名
{
值1,
值2,
值3,
…
} -
out参数返回
static void Main(string[] args) { int n; bool b; string s = Test(out n, out b); Console.WriteLine(s); Console.WriteLine(n); Console.WriteLine(b); Console.ReadKey(); } public static string Test(out int number, out bool b)//我想再返回一个int类型的100 { number = 100; b = false; return "张三"; }
-
ref参数
ref参数侧重于将一个变量以参数的形式带到一个方法中进行改变,改变完成后,再讲改变后的值带出来。
在使用ref参数的时候需要注意:ref参数在方法外必须为其赋值。 -
params
params可变参数:将实参列表中跟可变参数数组类型一样的参数当做是可变参数数组中的元素。
可变参数必须形参列表中的最后一个元素。static void Main(string[] args) { //求任意数字中的总和 int sum = GetSum(1.5,2,3,4,5,6); Console.Write(sum); Console.ReadKey(); } public static int GetSum(double d,params int[] nums) { int sum = 0; for (int i = 0; i < nums.Length; i++) { sum += nums[i]; } return sum; }
类的一些知识
类是不占内存的,而对象是占内存的
-
静态和非静态的区别
静态成员需要被static修饰,非静态成员不需要加static。
问题1:在一个非静态类中,是否允许出现静态成员?
答:非静态类中是可以出现静态成员的。
问题2:在非静态函数中,能不能够访问到静态成员?
答:在非静态函数中,既可以访问到非静态成员,也可以访问到静态成员。
问题3:在静态函数中,能不能够访问到非静态成员?
答:静态方法只能够访问到静态成员。
问题4:在静态类中能否出现非静态成员?
答:不可以,在静态类中,只允许出现静态成员。
在调用上,静态和非静态的区别
1、在调用实例成员的时候,需要使用对象去调用
2、在调用静态成员的时候,必须使用类名.静态成员名;
3、静态类是不允许创建对象的 -
属性的作用
保护字段
public class Person { private string _name; public string Name { get { return _name; } set { _name = value; } } char _gender; public char Gender { get { if (_gender != '男' && _gender != '女') { return _gender = '男'; } return _gender; } set { _gender = value; } } int _age; public int Age { get { return _age; } set { if (value < 0 || value > 100) { value = 0; } _age = value; } } public void SayHello() { Console.WriteLine("{0}---{1}--{2}",this.Name,this.Age,this.Gender); } }
-
在一个项目中引用另一个项目的类
- 添加要引用的类所在的项目。
- 代码顶引用命名空间
-
字符串的各种方法
- ToCharArray():将字符串转换成char类型的数组
- new string(char[] chs):将一个字符数组转换成一个字符串
- ToUpper():表示将一个字符串转换成大写形式。
- ToLower():表示将一个字符串转换成小写形式。
- Equals(“要比较的串”,StringComparison.OrdinalIgnoreCase):比较字符串,忽略大小写
- Split(new char[],{‘要分割的字符串’},StringSplitOption.RemoveEmptyEntries):分割字符串,返回一个字符串类型的数组
- Substring():截取字符串
- string Replace(string oldValue, string newValue)
- string Substring(int startIndex),取从位置startIndex开始一直到最后的子字符串;
- Substring(int startIndex, int length),取从位置startIndex开始长度为length的子字符串,如果子字符串的长度不足length则报错。
- bool Contains(string value)判断字符串中是否含有子串value
- bool StartsWith(string value)判断字符串是否以子串value开始;
- bool EndsWith (string value)判断字符串是否以子串value结束;
- int IndexOf(string value):取子串value第一次出现的位置
-
里氏转换
- 子类可以赋值给父类。
- 如果这个父类中装的是子类对象,那么可以将这个父类强转为子类对象。
- is:类型转换 ,如果转换成功,返回一个true,否则返回一个false。
- as:类型转换,如果转换成功,则返回对应的对象,如果转换失败,返回一个null。
public class Person { } public class Student : Person { } public class Teacher : Person { } //如果这个父类中装的是子类对象,那么可以将这个父类强转为对应的子类对象 Person p = new Student(); Teacher t = p as Teacher; Student s = p as Student; Console.ReadKey(); if (p is Student) { Student s = (Student)p; Console.WriteLine("成功"); } else { Console.WriteLine("不能转换!!!"); }
-
File类的方法
- File.Copy(“source”, “targetFileName”, true);//文件拷贝,true表示当文件存在时“覆盖”,如果不加true,则文件存在报异常。
- File.Exists();//判断文件是否存在
File.Move(“source”, “target”);//移动(剪切),思考如何为文件重命名? - File.Delete(“path”);//删除。如果文件不存在?不存在,不报错
- File.Create(“path”);//创建文件
-
两个关键字
- sealed:表示密封类,一旦被次关键字修饰,将表示这个类不能被继承.密封类不可以被其他类继承,但是,可以去继承其他类
- partial:部分类,分开编辑同一个类
-
多态
-
多态:一个对象能够表现出多种的状态
实现多态的几种办法:虚方法、抽象类、接口
虚方法:首先将父类的方法标记为虚方法,标记为虚方法就意味着这个方法可以被子类重写。public class Person { string _name; public string Name { get { return _name; } set { _name = value; } } public Person(string name) { this.Name = name; } public virtual void SayHello() { Console.WriteLine("大家好,我是人类,我叫{0}",this.Name); } } public class Chinese : Person { public Chinese(string name) : base(name) { } public override void SayHello() { Console.WriteLine("大家好,我是中国人,我叫{0}",this.Name); } } Person p = new Chinese("张三") p.SayHello();
抽象类
-
抽象成员必须标记为abstract,并且不能有任何实现。
-
抽象成员必须在抽象类中。
-
抽象类不能被实例化
-
子类继承抽象类后,必须把父类中的所有抽象成员都重写。
(除非子类也是一个抽象类,则可以不重写) -
抽象成员的访问修饰符不能是private
-
在抽象类中可以包含实例成员。
并且抽象类的实例成员可以不被子类实现 -
抽象类是有构造函数的。虽然不能被实例化。
-
如果父类的抽象方法中有参数,那么。继承这个抽象父类的子类在重写父类的方法的时候必须传入对应的参数。
如果抽象父类的抽象方法中有返回值,那么子类在重写这个抽象方法的时候 也必须要传入返回值。
public abstract class Shape { public abstract double GetPerimeter(); public abstract double GetArea(); } public class Circle : Shape { public Circle(double r) { this.R = r; } public double R { get; set; } public override double GetArea() { return Math.PI * this.R * this.R; } public override double GetPerimeter() { return 2 * Math.PI * this.R; } } public class Square : Shape { public double Chang { get; set; } public double Kuan { get; set; } public Square(double chang, double kuan) { this.Chang = chang; this.Kuan = kuan; } public override double GetArea() { return this.Chang * this.Kuan; } public override double GetPerimeter() { return (this.Chang + this.Kuan) * 2; } } Shape shape = new Square(5, 6);//new Circle(5); double area = shape.GetArea(); double perimeter = shape.GetPerimeter(); Console.WriteLine("这个形状的面积是{0:0.00},周长是{1:0.00}",area,perimeter);
接口
接口是一种规范。 只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员 为了多态。 接口不能被实例化。 也就是说,接口不能new(不能创建对象) 接口中的成员不能加“访问修饰符”,接口中的成员访问修饰符为public,不能修改 (默认为public) 接口中的成员不能有任何实现(“光说不做”,只是定义了一组未实现的成员)。 接口中只能有方法、属性、索引器、事件,不能有“字段”和构造函数。 接口与接口之间可以继承,并且可以多继承。 接口并不能去继承一个类,而类可以继承接口 (接口只能继承于接口,而类既可以继承接口,也可以继承类) 实现接口的子类必须实现该接口的全部成员。 一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面。 class MyClass:A,IA{},因为类是单继承的。 显示实现接口的目的:解决方法的重名问题 什么时候显示的去实现接口: 当继承的借口中的方法和参数一摸一样的时候,要是用显示的实现接口 当一个抽象类实现接口的时候,需要子类去实现接口。
//显示实现接口 class Program { static void Main(string[] args) { IEatable eat = new MQBird(); eat.Eat(); Console.ReadKey(); } } public class MQBird:IEatable { public void Eat() { Console.WriteLine("麻雀会吃"); } void IEatable.Eat() { Console.WriteLine("接口中的吃"); } } public class QQBird:IEatable { public void Eat() { Console.WriteLine("企鹅也会吃"); } void IEatable.Eat() { Console.WriteLine("接口中的吃方法"); } } //接口 public interface IEatable { void Eat(); void Fly(); }
-
-
集合
-
Arraylist集合
- Add():添加单个元素
AddRange():添加集合
Clear():清空集合中所有的元素
Remove():删除集合中的元素,括号里写谁,集合就删谁
RemoveAt():根据索引去删除集合中的元素
RemoveRange():删除一定范围内的元素
Insert():向集合的指定位置插入一个元素
InsertRange():向集合的指定位置插入一个集合
Contains():判断集合中是否包含某个元素
Sort():升序排列
ArrayList list = new ArrayList();//数组 //集合的长度可以任意改变 list.Add(1); list.Add(10.5); list.Add(true); list.Add("张三"); Person p = new Person(); list.Add(p); list.Add(new int[] { 1, 2, 3, 4, 5 }); list.Add(list); for (int i = 0; i < list.Count; i++) { if (list[i] is Person) { ((Person)list[i]).SayHello(); } else if (list[i] is int[]) { for (int j = 0; j < ((int[])list[i]).Length; j++) { Console.WriteLine(((int[])list[i])[j]); } } else if (list[i] is ArrayList) { } else { Console.WriteLine(list[i]); } }
- Add():添加单个元素
-
Hashtable
//字典 hello---->中文解释 键值对集合 Hashtable ht = new Hashtable(); ht.Add(1, "张三"); ht.Add('c', true); ht.Add(3.14, 100); ht.Add(2, "张三"); //使用下面这种方式向集合中添加相同的键不会抛异常 ht[2] = "李四";//键是5 值 李四 // ht.Clear(); ht.Remove(1);//根据键去删除数据 if (ht.ContainsKey(1)) { Console.WriteLine("已经具有相同的键"); } else { ht.Add(1, "王五"); } foreach (var item in ht.Keys) { Console.WriteLine("键----{0},值----{1}",item,ht[item]); } Console.ReadKey(); for (int i = 0; i < ht.Count; i++) { Console.WriteLine(ht[i]);//i 0 1 2 ht[0] ht[1] ht[2] } Console.ReadKey();
-
List泛型集合
List<int> list = new List<int>(); list.Add(1); list.Add(2); list.AddRange(new int[] { 1, 2, 3, 4, 5 }); list.AddRange(list); //将集合转换成数组 List<string> listTwo = new List<string>(); listTwo.ToArray() List<byte> list1 = new List<byte>(); list1.ToArray() for (int i = 0; i < list.Count; i++) { Console.WriteLine(list[i]); } foreach (int item in list) { Console.WriteLine(item); } Console.ReadKey();
-
Dictionary
Dictionary<int, string> dic = new Dictionary<int, string>(); dic.Add(1, "张三"); dic.Add(2, "李四"); dic.Add(3, "王五"); dic[4] = "赵六"; dic[2] = "哈哈"; //lamda表达式 foreach (KeyValuePair<int,string> item in dic) { Console.WriteLine("{0}-------{1}",item.Key,item.Value); } foreach (var item in dic.Keys) { Console.WriteLine("{0}---{1}",item,dic[item]); } for (int i = 0; i < dic.Count; i++) { Console.WriteLine(dic[i]); }
读写文件操作
- File类的读写(不常用)
//按行读取
string[] str = File.ReadAllLines(@"C:\Users\SpringRain\Desktop\4.txt",Encoding.Default);
for (int i = 0; i < str.Length; i++)
{
Console.WriteLine(str[i]);
}
//读取所有文本
string str = File.ReadAllText(@"C:\Users\SpringRain\Desktop\0326远程班学员机器码.txt",Encoding.Unicode);
Console.WriteLine(str);
Console.ReadKey();
//按字节读取
byte[] buffer = File.ReadAllBytes(@"C:\Users\SpringRain\Desktop\0326远程班学员机器码.txt");
//把字节数组解码成我们认识的字符串
string str = System.Text.Encoding.UTF8.GetString(buffer);
for (int i = 0; i < buffer.Length; i++)
{
Console.WriteLine(buffer[i].ToString());
}
//1024byte=1kb
//1024kb=1M
//1024M=1G
//1024G=1T
//1024T=1P
//会覆盖源文件
File.WriteAllLines(@"C:\Users\SpringRain\Desktop\new.txt", new string[] { "1", "2", "3" });
//也会覆盖源文件内容
File.WriteAllText(@"C:\Users\SpringRain\Desktop\new.txt", "今天");
//这三种写入方式都会覆盖源文件
string str="今天天气好晴朗,处处好风光";
//将字符串转换成字节数组
byte[] buffer= System.Text.Encoding.Default.GetBytes(str);
File.WriteAllBytes(@"C:\Users\SpringRain\Desktop\new.txt", buffer);
Console.WriteLine("写入成功");
//追加着向文件中写入数据
File.AppendAllText(@"C:\Users\SpringRain\Desktop\new.txt", "我是新来的",Encoding.GetEncoding("gb2312"));
Console.WriteLine("追加成功")
//复制文件
byte[] buffer = File.ReadAllBytes(@"C:\Users\SpringRain\Desktop\1、复习.wmv");
File.WriteAllBytes(@"D:\new.wmv", buffer);
Console.WriteLine("复制成功");
-
Filestream文件流读写文件
public static void CopyFile(string source, string target) { using (FileStream fsRead = new FileStream(source, FileMode.OpenOrCreate, FileAccess.Read)) { using (FileStream fsWrite = new FileStream(target, FileMode.OpenOrCreate, FileAccess.Write)) { byte[] buffer = new byte[1024 * 1024 * 5]; while (true) { //返回本次读取实际读取到的有效字节数 int r = fsRead.Read(buffer, 0, buffer.Length); //在写入的时候 应该写入实际读取到的有效字节数 fsWrite.Write(buffer, 0,r); if (r == 0) { break; } } }
-
StreamWriter和StreamReader
//使用StreamReader来读取数据 using (StreamReader sr = new StreamReader(@"C:\Users\SpringRain\Desktop\抽象类特点.txt",Encoding.Default)) { while (!sr.EndOfStream) { string str = sr.ReadLine(); Console.WriteLine(str); } } Console.ReadKey(); //使用StreamWriter来写入数据 using (StreamWriter sw = new StreamWriter(@"C:\Users\SpringRain\Desktop\ooo.txt",true)) { sw.Write("lalalaala"); } Console.WriteLine("写入成功"); Console.ReadKey();
Winform
-
打开文件对话框
OpenFileDialog ofd = new OpenFileDialog(); //设置打开对话框显示的文本 ofd.Title = "请选择文件哟亲~~"; //设置打开对话框可以多选 ofd.Multiselect = true; //设置打开对话框的初识目录 ofd.InitialDirectory = @"C:\Users\SpringRain\Desktop\Resources"; //设置打开对话框文件的类型 ofd.Filter = "媒体文件|*.wav|图片文件|*.jpg|文本文件|*.txt|所有文件|*.*"; ofd.ShowDialog(); //获得所有选中文件的全路径 string[] str = ofd.FileNames;
-
保存文件对话框
SaveFileDialog sfd = new SaveFileDialog(); sfd.InitialDirectory = @"C:\Users\SpringRain\Desktop"; sfd.Title = "请选择要保存的路径"; sfd.Filter = "文本文件|*.txt|所有文件|*.*"; sfd.ShowDialog(); //获得保存的文件的路径 string path = sfd.FileName; if (path == "") { return; } //除去文本的空格值 string text = textBox1.Text.Trim(); using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { byte[] buffer = System.Text.Encoding.Default.GetBytes(text); fsWrite.Write(buffer, 0, buffer.Length); } MessageBox.Show("保存成功");
-
窗体间控件移动
public partial class Form1 : Form { public Form1() { InitializeComponent(); } Form2 frm2 = new Form2(); private void label1_Click(object sender, EventArgs e) { //判断 如果label在第一个窗体中 //点击的时候 让它去第二个窗体中 if (this.label1.Parent == this) { //将窗体1中label添加到窗体2中 frm2.Controls.Add(this.label1); this.label1.Text = "我现在窗体2中"; frm2.Show(); } else//在第二个窗体中 { this.Controls.Add(this.label1); this.label1.Text = "我现在窗体1中"; } } }
-
线程的使用
public Form1() { InitializeComponent(); } Thread th; bool b = false; private void button1_Click(object sender, EventArgs e) { if (b==false) { b = true; th = new Thread(GameStart); th.IsBackground = true; th.Start(); button1.Text = "暂停"; } else { b = false; button1.Text = "开始"; } } public void GameStart() { Random r = new Random(); while (b) { try { label1.Text = r.Next(0, 10).ToString(); label2.Text = r.Next(0, 10).ToString(); label3.Text = r.Next(0, 10).ToString(); } catch { } } } //允许垮线程访问 private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; } //程序结束关闭线程,线程关闭后无法再打开 private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (th != null) { th.Abort(); } }
-
委托的用法
-
委托基本语法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _02委托语法 { public delegate void DelSayHello(string name); class Program { static void Main(string[] args) { //声明的委托必须跟指向的方法具有同样的签名 //调用委托 //首先创建委托对象 DelSayHello del = JapaneseSayHello;//new DelSayHello(JapaneseSayHello); // //Test() del("张三"); Test("张三", JapaneseSayHello); // Console.ReadKey(); ChineseSayHello("张三"); Console.ReadKey(); } public static void Test(string name,DelSayHello del) { del(name); } public static void ChineseSayHello(string name) { Console.WriteLine("你好:"+name); } public static void JapaneseSayHello(string name) { Console.WriteLine("o ha yo"+name); } } }
-
泛型委托和lamda表达式
namespace 泛型委托 { //泛型委托 public delegate int Delcompare<T>(T n1,T n2); public delegate void Deltest();//lamda委托 class Program { static void Main(string[] args) { int[] num = { 1, 2, 3, 4 }; string[] names = { "sdasd", "sdsd", "ssssssssss" }; person[] people = { new person() {Age=12 },new person() { Age=22} }; string max = GetMax(names, Compare2); person p = GetMax(people, Compare3); Console.WriteLine(p.Age); Console.WriteLine(max); //lamda表达式(参数)=>{函数体和返回值} Deltest del = () => { Console.WriteLine("lamda函数"); }; del(); //lamda表达式的应用,移除大于2的元素 List<int> list = new List<int>{ 1, 2, 3, 4, 5, 6 }; list.RemoveAll(n=>n>2); for (int i = 0; i < list.Count; i++) { Console.WriteLine(list[i]); } } //返回任意数组中的最大值 public static T GetMax<T>(T[] nums, Delcompare<T> del) { T max = nums[0]; for (int i = 0; i < nums.Length; i++) { if (del(max, nums[i]) < 0) { max = nums[i]; } } return max; } public static int Compare1(int n1, int n2) { return n1 - n2; } public static int Compare2(string n1, string n2) { return n1.Length - n2.Length; } public static int Compare3(person n1, person n2) { return n1.Age - n2.Age; } } public class person { public int Age { get; set; } } }
-
-
窗体控件传值
窗体1中的label想获取窗体2中的text值,在窗体1中写好label控件赋值的方法,在窗体2中写好该方法的委托。窗体2的构造函数添加委托的赋值,并在按钮按下将text传给委托,在窗体1生成窗体2的时候,将label赋值的方法传给窗体2的构造。这样窗体2就拿到了窗体1的方法。namespace _08委托案例_窗体传值 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //将赋值的方法传给了窗体1 Form2 frm2 = new Form2(SetLable); frm2.Show(); } /// <summary> /// 窗体一主要任务就是给lable赋值 /// </summary> /// <param name="s"></param> private void SetLable(string s) { label1.Text = s; } } }
namespace _08委托案例_窗体传值 { public delegate void DelTest(string s); public partial class Form2 : Form { public DelTest _del; public Form2(DelTest del) { this._del = del; InitializeComponent(); } //调用委托函数,其实就是调用窗体1的赋值函数 private void button1_Click(object sender, EventArgs e) { _del(textBox1.Text); } } }