c# learing(2)

1、集合
就是一种存放多种数据的复杂类型。
2、基本集合类型
动态数组 ArrayList
列表 :List
栈 Stack
字典 Dictionary
队列 Queue
3、动态数组ArrayList
初始化,可以不指定大小
获取长度,使用Count属性
添加是使用Add
删除用Remove,RemoveAt
访问[index]
4、List<T>
ArrayList是类型不安全,而且有装箱拆箱的性能问题,所以有了List<T>

1、字典Dictionary<TKey,Tvalue>
字典容器存储的是一系列的键值对,没个值对应一个唯一的键。键的意义在于,我们可以通过键相对高效的访问到值。
2、字典操作
数量 Count
添加 Add(key,value)
删除 Remove
访问 [key]
3、栈
出栈 Pop
入栈 Push
获取栈顶元素 Peek
4、队列
先进先出容器。
出队 Dequeue
入队 Enqueue,有返回值

装箱和拆箱
1、装箱:根据值类型的值,在堆上创建一个完整的引用类型对象,并返回对象的引用,是一种隐式转换(语言自动完成)。
2、为什么要装箱
有时候需要将值类型转化为引用类型(比如object)来进行统一的操作(比如作为函数的参数)和统一的存储(比如object[])。
3、装箱简单实例
int i=3;
object oi=null;
oi=i;//发生装箱,原来的int保持不变,创建了一个新的对象,该对象在堆当中。需要性能消耗的。
4、装箱的本质
就是在对上创建了一个引用类型的副本,新创建的引用类型和原来的值类型相互独立。
相互独立代码验证:
int i=3;
object oi=i;//发生装箱
Console.WriteLine("i="+i+",oi="+oi.ToString);//输出为i=3,oi=3
oi=10;
i=7;
Console.WriteLine("i="+i+",oi="+oi.ToString);//输出为i=7,oi=10
说明两者相互独立
5、拆箱
将装箱后的对象转化回值类型的过程,是一种显示转换(需要手动干预)。
6、拆箱实例
in i=3;
object oi=i;//装箱
int j=(int)oi;//拆箱

自定义转换
1、概念
为自己的类定义和结构显示和隐式转换
2、为什么需要自定义转换
使自己的结构和类型可以变成一个预期相关的类型(比如我想将我家的狗狗转化为猫咪),并且使这种转化更加简单。
3、隐式转换语法
注意
public static implicit operator Dog(Cat cat)//implecit指定为隐式转换,operator指定为转换,参数为需要转化的类型,operator后是目标类型
{
···
}
4、显示转换
public static explicit operator Cat(Dog dog)
5、转化实例
public static implicit operator Cat(Dog dog)//将狗狗转化为猫咪
{
return new Cat(dog.name);
}
//将猫咪转化为狗狗
public static explicit opterator Dog(Cat cat)//显示转换
{
return new Dog("Tom");
}
···
Dog dog=new Dog("Jack");
dog.Speak();
Cat cat=dog;
cat.Spesk();
Dog dog2=(Dog)cat;
dog2.Speak();

1、什么是重载运算符
不能创造新的运算符,所以利用现有的某种运算符,针对自定义类或者结构(预定义类型和现有运算符的运算含义是确定的所有不能更改),定义某种运算符(该运算符和该操作具有一定相关性,如公狗狗+母狗狗=新生狗狗),从而简化自定义类型的操作。
2、语法细节
public static Dog operator +(Dog male,Dog female)//如公狗狗+母狗狗=新生狗狗
{
···
}
3、那些运算符可以重载
一元运算符:+、-、!、~、++、- -、true、false(操作数必须是类和结构)
二元运算符:+、-、*、%、&、|!、^、<<、>>、= =、!=、>、<、>=、<=(两个操作数至少有一个表示类或者结构)
不能重载:=、&&、||、[](索引操作)、()等
4、重载运算符不能做什么
创造新运算符
改变运算符语法
重定义运算符如何处理预定义类型
改变运算符的优先级和结合性
5、重在运算符举例
···
public void ShowAge()
{
Console.WriteLine("Age="+_age);
}
···
//重载自增操作,针对宠物的年龄
public static Pet opertor ++(Pet pet)//返回值为Pet类型,参数为宠物自身。所有的重载方法都需要public static修饰
{
++pet._age;
return pet;
}
···
Dog dog=new Dog("Jack");
dog._age=2;
dog++;
dog.ShowAge();


1、泛型类就是一个模子,放入类型的材料(字段属性方法),可以塑造出想要的产品。
2、语法
class Cage<T>//这是一个笼子类和泛型类,类名后加上一对<>,加上一个泛型参数
{
T[] petArray;//定义T类型的数组
public void PutIn(T pet){···}//放入T类型的宠物
public T TakeOut(int index){···}//占位符T,cage类变为具体类时,T相应的变成具体数
}
//实例化
var dogCage=new Cage<Dog>();//得到狗狗笼子
var catCage=new Cage<Cat>();//得到猫咪笼子
3、为什么需要泛型,用基类(包括所有类的基类object)或者公共的接口也可以实现一个Cage类,但是类型太宽泛,需要显示转换类型并判断真是类型是什么。
4、泛型使用:声明一个泛型类->引用泛型->构造实例
class Cage<t>{···}
class Cage<Dog>{···}
dogCage=new Cage<Dog>;

比如不写Petcage<Dog> dog=new Petcage<Dog> ("名字");而用一个从来没见过的 var代替。还有 return default<T>也没解释啥意思
理解:泛型就是在不确定类的参数类型和返回类型时,设置一个变量来代替这个固定的类型。当创建类实例时,在给这个变量赋对应类类型值,这样就可以实现一个类,输出不同类型的值和方法。
不用老师的例子,用一个给数组赋值输出数组的例子更好理解;如设置一个类,构造函数初始化一个数组数组类型为int,有给数组赋值方法和获取数组值的方法,在此注意:数组的类型int和获取数组值的方法的返回值类型都为int,如果实例此类调用方法,实参和返回值类型也必须是int;就此限定死了此类的实例; 如果想要一个设置char类型的实例,还得必须创建一个新的char的类和方法才能实现;这样代码工作量很大;若使用泛型,用变量<T>代替固定类型int或char,这样在实例化的时候,将T赋不同类型(int、double、char)就可以获得想要的返回值类型,从而实现了一个模板,只变一个参数T就能实现相同的功能
上面给出的例子。只需要把所有<T>去掉,后面的T全改为int或char 就能变为普通类了。对比理解非常简单了

1、什么是泛型方法:就是方法的模型,给定具体的类型,就可以实例化出一个操作该类型的具体方法。
注意:泛型类中可以有泛型方法,普通类中也可以有泛型方法。
2、泛型方法语法
class Dog{
void DogIsHappy<T>(T target){//普通类中的泛型方法
···
}
}
实例
public void isHappy<T>(T target)
{
Console.Write("happy"+target.ToString())
}
class Person{}
...
var dog=new Dog("A");
dog.isHappy<Person>(new Person());
dog.isHappy<int>(3);
一个类的实例对象就相当于这个类类型的值;
比如 int 4;4是int类型的值;
Person new person() ;new person()是Person类型的值或实例; 其实就相当于创建一个Person类,然后Person person=new Person(); person 就是Person的一个类型值


1、什么是约束
约束就是控制泛型这匹烈马的缰绳!缩小泛型参数的范围(无论多么泛泛,总有一个范围,范围越小越好控制)
2、约束的意义
只有添加了约束,才能调用泛型参数中(比如T)的方法。
对泛型类和方法都可添加约束。
3、约束的类型
类名 ——该类或者继承该类的类
class ——任何类
struct ——任何值
接口名 ——该接口类型或任何实现该接口的类型
new() ——带有无參共有构造函数的类
4、约束叠加规则(这三个约束可以任意存在)
A、主约束,只能有一个(类名,class,struct)
B、接口约束,可以有任意多个
C、构造约束
5、约束例子
void Cage<T,M>
where T:Pet,IClibTree,new()//where约束哪个类型参数
where M:Pet,IClibTree,new()
{···}

委托是持有一个或者多个方法的对象!并且该对象可以执行,可以传递。
定义委托
delegate void ActCute();
声明委托
ActCute del = null;
Dog dog = new Dog("A");
Cat cat = new Cat("B");
让委托持有方法
del = dog.WagTail;
del += cat.InnocentLook;
执行委托
del();

Lambda表达式
1、什么是匿名方法
delegate void ActCute();
ActCute del;
del=delegate(){//方法的具体内容};//声明一个匿名方法
2、Lambda表达式
del=delegate(){};
del=()=>{···};

扫描二维码关注公众号,回复: 70429 查看本文章

定义委托
public delegate void Handler();
定义事件
public event Handler NewDog;
构造函数
public Dog(string name):base(name)
{
++Num;
if(NewDog!=null)
{
NewDog();
}
}
Client c1 = new Client();
Client c2 = new Client();
Dog.NewDog += c1.WantADog;
Dog.NewDog += c2.WantADog;
Dog dog = new Dog("Q");

猜你喜欢

转载自www.cnblogs.com/abc3288288351/p/8951746.html
今日推荐