1.泛型约束
(1 class泛型T必须是引用类型
(2 struct泛型T必须是值类型
(3 new() 泛型T必须是包含一个无参构造方法是class,如果同时其他约束,new()必须放在最后
(4 类名 泛型T要么是Parseon类型,要么是Person的子类/孙子类
(5 接口约束 泛型T必须实现一个或多个接口
(6 多占位符约束 使用where关键字对多个占位符进行约束
//1. class 引用类型
class MyGenericClass<T> where T : class
{
}
MyGenericClass<string> m = new MyGenericClass<string>();
//2.struct 值类型
class MyGenericClassForValueType<T> where T : struct
{
}
MyGenericClassForValueType<float> f = new MyGenericClassForValueType<float>();
//3.new()当前的T 必须包含无参构造方法
class MyGenericClassForNew<T> where T : class, new()
{
}
MyGenericClassForNew<TestForNew> m2 = new MyGenericClassForNew<TestForNew>();
//5.接口约束 泛型T必须实现一个或多个接口
class Tank : Machine, IFireable, IRnnable
{
}
MyGenericClassFroInterface<Tank> m4 = new MyGenericClassFroInterface<Tank>();
//6多类型占位符约束
class MyGenericClassForMulti<T, B> where T : class, new() where B : IFireable, IRnnable
{
}
MyGenericClassForMulti<TestForNew, Tank> m5 = newMyGenericClassForMulti<TestForNew, Tank>();
2.ArrayList不可变数组
1.ArrayList大小是按照其中存储的数据来动态扩充与收集的
2.ArrayList可以很方便地进行数据的添加插入删除
3.ArrayList可以存储任意类型
4.ArrayList在存储和读取数据时 会进行装箱和拆箱 影响程序性能
创建对象 ArrayList 名字=new ArrayLis()
(1增
(1.2.add()末尾添加元素 返回值为添加元素的索引值,元素类型为object 可以添加任意类型
(1.3 范围添加元素 可以直接添加 继承ICollection的集合的对象
(1.4 插入元素 Insert(参数1 索引值,参数2 插入的元素)
(2删
(2.1 Remove()按元素删除元素,删除匹配第一个元素
(2.2 RemoveRange(参数1 开始的索引值,参数2 删除的长度) 范围删除元素
(2.3 Clear()清空元素
(3改
(3.1 数组名[索引值] =”修改后的值“
(4查
(4.1 IndexOf()查询数组是否在某个元素 存在返回其索引值 反之返回-1
3.List 泛型集合
List与其他数组的比较
List与可变数组吗(Array类)比较类似 都是存放类型相同的元素
List与可变数组(ArrayList)比较类似 元素长度不固定
创建泛型集合对象 存储的元素类型string
(1增
(1.2.add()末尾添加元素 返回值为添加元素的索引值,元素类型为object 可以添加任意类型
(2删
(2.1RemoveAt()删除指定的值
(2.2 Remove() 通过值来删除记录
(3改
(3.1 数组名[索引值] =”修改后的值“
(4查
(4.1 Contains() 方法判断List中是否包含某个值
(4.2 Reverse() 方法可将数组的值倒过来排列
(4.3 indexof()可以查询指定值在List中序号,序号从0开始结束的找不到就返回-1
4. Dictionary字典类
1.Dictionary 没有索引值 只有Key/Value
2.key/Value都可以是任何类型
3.Dictionary是可变长度的集合
4.Dictionary是泛型的集合 定义对象时 要指定 key/Value的类型
5.通过key值查询value 且key值是唯一
创建对象
Dictionary<string,int> keyValuePairs = new Dictionary<string, int>();
(1增
(1.1 add(”string“,int)添加
(2删
(2.1Remove()删除value元素
(2.2 Clear();清空
(3改
(3.1名字[]=
(4查
ContainsKey()查到了返回true 反之返回false
5.结构
(1结构体是值类型 关键字Struct
(2类是引用类型
(3引用类型均隐式继承 System.Object 而值类型均隐式继承 System.ValueType
(4 所有的整数类型和浮点数类型 本质都是一个结构体
(5 结构可带有方法 字段 属性 运算符 委托和事件
(6 结构可实现一个或多个接口 但是不能继承其他类 和机构体
(7结构不支持被其他类继承
(8结构类似与密封装类 不能使用virtual或 protected
(9.结构的默认修饰符是internal
(10 结构体也可以使用构造创建对象
2.1 扩展
is 判断对象是否为某一类型。ValueType 代表值类型的基类
int a =1;
Console.WriteLine(a is ValueType); // true
6.枚举
作用
(1枚举能使代码更清晰,描述一组整数值 使数字更具有具体意义
(2 枚举是值类型 包含一组数字常量的类型
(3 关键字 enum
(4 枚举可以在类的内部定义 也可以和类平级
(5枚举是一组整型常量 默认是从0开始 也可以自定义范围
每一个描述内容 都代表一个数字 默认从上到下 从0开始
enum MyEnum
{
chifan,
shuijiao,
dadoudou,
gouwu,
lvyou
}
7.委托 课件 zhiyou_Day15_1
(1 委托就是把方法(函数)变成一种引用类型的方式
(2 委托 关键字 delegate
(3 委托分为定义委托和使用委托(定义方法)和使用委托(使用方法)
(4 定义委托和定义类一样可在命名空间中定义,也可以像变量一样在类的内部定义
(5委托可以使用修饰符public,private,protected等, 一般使用public委托的默认修饰符是internal。
(6 委托可以根据不同类型的方法(有参无参 返回值 无返回值等)定义多个委托类型
委托分为 无参 有参 无返回值 有返回值 泛型委托
2.1 无参
//定义无参返回值的委托
delegate void MyDelegate();
//创建委托类型的对象 用来管理某个符合要求的方法
MyDelegate myDelegate1 = new MyDelegate(aaa);
//调用
myDelegate1();
public static void aaa()
{
Console.WriteLine("无返回值无参数的方法");
}
2.2有参
//委托定义有参返回值
delegate string MyDelegate4(string a, string b);
MyDelegate4 myDelegate4 = new MyDelegate4(ddd);
//调用
string name = myDelegate4("zhanhsan", "lisi");
2.3 有返回值
//有返回值的委托
delegate string MyDelegate4(string a, string b);
MyDelegate4 myDelegate4 = new MyDelegate4(ddd);
//调用
string name = myDelegate4("zhanhsan", "lisi");
//方法
public static string ddd(string a, string b)
{
Console.WriteLine("有返回值类型string有两个string类型参数的方法:{0},{1}", a, b);
return a + b;
}
2.4泛型委托
//泛型委托
public delegate void MyDelegate6<T>(T a);
MyClass.MyDelegate6<int> myDelegate61 = new MyClass.MyDelegate6<int>(ProgramMothod1);
//调用泛型委托
myDelegate61(200);
public static void ProgramMothod1(int a)
{
Console.WriteLine(a);
}
3.1 使用委托作为方法参数
//定义无参无返回值的委托
delegate void MyDelegate();
//使用委托作为方法参数
public static void ProgramMothod(int a, string b, MyDelegate myDelegate)
{
Console.WriteLine(a);
Console.WriteLine(b);
myDelegate();
}
ProgramMothod(100, "321", myDelegate, myDelegate2, 400, 500);
4.1 Action和Func委托 ZhiYouDay19_2
1. Action委托表示一个void返回类型的方法
//如果有参数 返回值类型在最后
Action<int> action1 = new Action<int> (ProgramMothod);
action1(10);
private static string ProgramMothod2(int a)
{
return a.ToString();
}
2. Func委托表示一个带返回类型的方法
//如果有返回值 返回值类型在最后
Func<int,string> func1 = new Func<int ,string>(ProgramMothod2);
private static string ProgramMothod2(int a)
{
return a.ToString();
}
5.1 委托的多播
1.方法的类型相同
2.同时执行
3.委托对象调用+=方式 完成多播的使用 -=起效多播操作
//定义委托一
MyDelegate myDelegate2 = new MyDelegate(ProgramMothod);
//定义委托二
MyDelegate myDelegate1 = new MyDelegate(ProgramMothod1);
//调用 委托一的时候把委托二带上
myDelegate2 += ProgramMothod1;
myDelegate2();
myDelegate2 -= ProgramMothod1;
myDelegate2();
//方法
static void ProgramMothod() {
Console.WriteLine("123");
}
static void ProgramMothod1()
{
Console.WriteLine("456");
}
8.事件
(1.事件基于委托的,可以为任何一种委托提供一种发布\订阅机制。(类似委托多播)
(2.使用event关键字将一个委托类型定义为事件 事件就是委托的一个对象(3 使用+=和-=来完成委托的多播的操作
普通匿名函数同学
1.针对委托的使用
2.可以快捷的使委托实例化
3.不建议再使用匿名函数,后使用lambda表达式替代匿名函数
4.有三种常用的匿名还是:Lambda表达式 匿名方法和Func/Action委托。
//匿名还是的写法
class Program
{
delegate int MyDelegate(int a, int b);
static void Main(string[] args)
{
MyDelegate md = delegate(int a, int b) { return a + b; };
int sum = md(1,2);
Console.WriteLine(sum);
}
}
事件与普通匿名函数
nternal class Program
{
static void Main(string[] args)
{
Heater heater = new Heater();
heater.BoilEvent += delegate (int x) //添加匿名函数
{
Console.WriteLine("水已经{0}度了,可以用茶杯接水了", x);
};
heater.BoilEvent += delegate (int x) //添加匿名函数
{
Console.WriteLine("水已经{0}度了,可以用大桶接水了", x);
};
heater.BoilWater();//执行事件
}
}
public class Heater
{
private int temperature; //水温
public delegate void BoilHandle(int x); //声明关于事件的委托
public event BoilHandle BoilEvent; //声明水要烧开的事件
public void BoilWater()
{ //烧水的方法
for (int i = 0; i <= 100; i++)
{
temperature = i;
if (temperature > 96)
{
if (BoilEvent != null)
{
BoilEvent(temperature);
}
}
}
}
}
lambda表达式
1.普通匿名函数的升级版本(箭头函数)
比普通匿名函数更为简洁,数据类型可以不用写
class Program
{
delegate int MyDelegate(int a, int b);
static void Main(string[] args)
{
MyDelegate md = (a,b)=>{return a+b;};
int sum = md(1, 2);
Console.WriteLine(sum);
}
}
事件与lambda表达式
internal class Program
{
static void Main(string[] args)
{
Heater heater = new Heater();
heater.BoilEvent += x =>
{
Console.WriteLine("水已经{0}度了,可以用茶杯接水了", x);
};
heater.BoilEvent += x=> //添加匿名函数
{
Console.WriteLine("水已经{0}度了,可以用大桶接水了", x);
};
heater.BoilWater();//执行事件
Console.ReadKey();
}
}
public class Heater
{
private int temperature;//水温
public delegate void BoilHandle(int x);//声明关于事件的委托
public event BoilHandle BoilEvent;//声明水要烧开的事件
public void BoilWater()
{ //烧水的方法
for (int i = 0; i <= 100; i++)
{
temperature = i;
if (temperature > 96)
{
if (BoilEvent != null)
{
BoilEvent(temperature);
}
}
}
}
}
9.运算符重载
1.含义
是对已有的运算符重新定义新的运算,以适应不同的数据类型
特点:
1.运算符重载的声明方式, operator 关键字
2.必须用public修饰且必须使类的静态的方法
3.重载运算符的方法,不用主动调用 只要使用重载的运算符就想当调用了方法
4.运算符只能采用值参数,不能采用ref或out参数
5.重载运算符的返回值不一定必须是自己,但一定不能是void
运算符 可重载性
! ++、--、 可以重载这些一元运算符
+、-、*、/、%、&、| 可以重载这些二元运算符
==、!=、<、>、<=、>= 可以重载比较运算符,必须成对重载
&&、|| 不能重载条件逻辑运算符,但可以使用能够重载的&和|进行计算
+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>= 不能显式重载赋值运算符,在重写单个运算符如+、-、%时,它们会被 隐式重写
=、.、?:、->、new、is、sizeof、typeof () [] 不能重载这些运算符
+ - * / % ++ -- !
public static Student operator +(Student stu1,Student stu2)
{
return new Student(stu1.Age + stu2.Age, stu1.Name + stu2.Name);
}
public static Student operator -(Student stu1, Student stu2)
{
return new Student(stu1.Age - stu2.Age, stu1.Name + stu2.Name);
}
public static Student operator ++(Student stu1)
{
stu1.Age++;
stu1.Height++;
return stu1;
}
public static bool operator !(Student stu1)
{
if (stu1.Age < 20)
{
return !false;
}
else {
return !true;
}
}
public static Student operator &(Student stu1,Student stu2)
{
if (stu1.Age < 20 && stu2.Age<10)
{
return new Student(stu1.Age + stu2.Age);
}
else
{
return new Student(stu1.Age - stu2.Age);
}
}
10.异常处理
含义:异常是在程序执行期间出现的问题,C#中的异常处理是对运行出现的特殊情况的一种响应
C# 异常出现四个关键字 try catch finally 和thorow
- try:一个 try 块包括一块要被检测异常的代码块
- catch:表示对异常的捕获和处理。
- finally:不管异常是否存在都会执行。
- throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
格式
try
{
// 引起异常的语句
}
catch( ExceptionName e1 )
{
// 错误处理代码
}
finally
{
// 要执行的语句
}
Flie创建文件
File写入文件
File.WriteAllText或File.WriteAllLines方法时 如果指定的文件路径不存在,会创建一个新文件,如果文件存在,会把之前的文件替换掉成新文件
WriteAllText(”读取字符串) WriteAllLines(字符串数组)
File读取文件
string path = @"E:\myFile.txt"
第一种ReadAllText(path ) 第二种ReadAllLines()
StreamReader写数据
string path = @"D:\myFile.txt";
StreamWriter streamWriter = new StreamWriter(path);
streamWriter.WriteLine("ABC");
streamWriter.WriteLine("DDD");
streamWriter.Write("HAHAH");
streamWriter.Write("ABVV");
streamWriter.Close();
StreamWriter读数据
string path = @"E:\myFile.txt";
StreamReader sr = new StreamReader(path, Encoding.UTF8);
string content = sr.ReadToEnd();
Console.WriteLine(content);
sr.Close();
追加数据
string path = @"D:\myFile.txt";
if (!File.Exists(path)) //检查文件是否存在
{
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); //创建
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine("input text"); //写入内容,自定义
sw.Close();
fs.Close();
}
else
{
FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write); //追加写入
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine("567"); //写入内容,自定义
sw.Close();
fs.Close();
}
删除 移动 复制
删除
string newFilePath = @"E:\myFile_new.txt";
File.Delete(newFilePath);
移动
string sourceFilePath = @"E:\myFile.txt";
string destinationFilePath = @"D:\myFile.txt";
File.Move(sourceFilePath, destinationFilePath);
复制
string sourceFilePath = @"E:\myFile.txt";
string destinationFilePath = @"E:\myFile_copy.txt";
File.Copy(sourceFilePath, destinationFilePath);