c# 泛型 - 学习笔记
2017-03-23 13:56
253 查看
/*接口
* 用来声明某些函数
* 基本结构
* public interface name
* {
* void name(param);
* }
* 接口只能包含方法,属性,索引器,和事件声明,
* 当一个类声明了接口,就必须实现这个接口下所有的方法,接口可以被多个不同的类声明,实现。
* 接口可以集成接口,派生类接口被一个类声明时,该类需要实现这个派生类接口以及父类接口的所有方法
*
* 泛型 类似于一个模子,
* 为什么使用泛型。泛型性能更加友好,类型更加安全,易于维护,修改。
* 例如 var list = new List();(未使用泛型)
* int i1 = (int)list[0]; 需要拆箱
*
* var list = new List<int>() 泛型定义为INT
* int l1 = list[0]l 不需要拆箱
*
* 其次,如果不设定泛型,第一个例子中的数组可以插入各种类型例如string 和类对象等
* 如果设定了泛型,数组就无法插入除开泛型以外的类型
*
* 命名规则,以T开头,如果只用了一个泛型参数,可以直接命名为T。
* 如public class list <T>
* -------------(简单理解,就是定义的时候,先一个T,作为一个标识符,到时候的时候再参照约束条件,确定写入类型)--------------
*
* 泛型方法
* 就是方法的模型,给定具体的类型,就可以实例化出一个操作该类的具体方法,泛型类中一般有泛型方法,普通类中也可以有泛型方法
*
* 约束,添加了约束,才能更加准确的调用方法,没有约束只能调用object的方法
* 约束的类型
* 类名 , class, struct ,接口名,new()
* 如果传入一个类,那就只能使用该类或者集成该类的派生类
* 如果传入一个class 那就说明可以是任何类
* 如果传入一个struct 说明可以传入任何值
* 如果传入的接口名,说明可以传入该接口类型或者任何实现该接口的类型
* 如果传入new(),说明可以传入带有 无参共有构造函数的类
* 约束规则
* A 主约束 B 接口约束 C 构造约束
* A 只能有一个,类名,class,struct
* B 能有任意多个
* 例如
* void cage<T>
* where T: Pet ,interface,new()
* 表示pet及其派生类,必须实现interface接口, 有默认构造函数
*
*
* 泛型接口
* 允许我们将接口成员的参数和返回类型设置为泛型
*
* interface Imyself<T>
* {
* T Myself(T self);
* }
*
* 协变与抗变
* 参数类型是协变得,如果有两个类,A派生自B,那么要求B类型的参数,可以填写A
* 方法类型是抗变得,如果一个方法返回 B, 那么返回类型只能是B ,不能是A,因为A 不一定是B,
* 但是如果一个方法返回是 A ,那么返回类型 可以为A也可以为B。
* 泛型接口使用OUT关键词就表示返回类型只能是T
* 如果使用IN关键字就表示T只能作为参数输入
*
*/
//代码示例
static void Main(string[] args)
{
//插入类
var dogCage = new Cage<Dog>(1);
dogCage.Putint(new Dog("a"));
dogCage.Putint(new Dog("b"));
var pet = dogCage.Takeout();
pet.printName();
//插入数字
var numCage = new Cage<int>(2);
numCage.Putint(5);
numCage.Putint(7);
numCage.Putint(9);
var nu = numCage.Takeout();
Console.WriteLine("take out "+nu.ToString());
//泛型方法举例 定义见dog类
var dog = new Dog("D");
dog.isHappy<person>(new person());
dog.isHappy<int>(6);
//泛型约束方法举例 定义见dog类
var dogE = new Dog("E");
dogE.isSad<Cat>(new Cat("Tom"));
//dogE.isSad<int>(8); //这里会报错,因为约束泛型只能是pet及其派生类
//泛型接口使用
Program gg = new Program();
gg.Act(new Dog("logan"));
gg.Act(new Cat("laola"));
}
//接口实现
public void Act(Dog pet)
{
pet.printName();
}
public void Act(Cat pet)
{
pet.printName();
}
}//泛型类
public class Cage<T>
{
T[] array;
readonly int Size;
int num;
public Cage(int n)
{
Size = n;
num = 0;
array = new T[Size];
}
public void Putint(T pet)
{
if (num < Size)
{
array[num++] = pet;
Console.WriteLine("get the pet");
}
else
{
Console.WriteLine("cage is full");
}
}
public T Takeout()
{
if (num > 0)
{
return array[--num];
}
else
{
Console.WriteLine("cage is empty");
return default(T);
}
}
}
//接口
public interface IDog<T> where T : Pet
{
void Act(T pet);
}
//pet 类
public class Pet
{
private string name;
public Pet(string name)
{
Name = name;
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
virtual public void speak()
{
Console.WriteLine("pet speaks");
}
virtual public void printName()
{
Console.WriteLine("My name is "+Name);
}
}
//继承自pet类的dog类
class Dog:Pet
{
public Dog(string name) : base(name)
{
Name = name;
}
public override void speak()
{
Console.WriteLine("Dog speaks wang wang");
}
//泛型方法
public void isHappy<T>(T target)
{
Console.WriteLine("Dog is happy to "+target.ToString());
}
//泛型方法+约束
public void isSad<T>(T target) where T: Pet
{
Console.Write("Dog is sad to ");
target.printName();
}
}
class Labrador : Dog
{
public Labrador(string name) : base(name)
{
Name = name;
}
}
//继承自pet类的cat类
class Cat:Pet
{
public Cat(string name) : base(name)
{
Name = name;
}
public override void speak()
{
Console.WriteLine("cat speaks miao miao");
}
}
代码可以在github上下载:https://github.com/lcxxxc/UWP_Readness
选择study_day3_part_two 的那一份
* 用来声明某些函数
* 基本结构
* public interface name
* {
* void name(param);
* }
* 接口只能包含方法,属性,索引器,和事件声明,
* 当一个类声明了接口,就必须实现这个接口下所有的方法,接口可以被多个不同的类声明,实现。
* 接口可以集成接口,派生类接口被一个类声明时,该类需要实现这个派生类接口以及父类接口的所有方法
*
* 泛型 类似于一个模子,
* 为什么使用泛型。泛型性能更加友好,类型更加安全,易于维护,修改。
* 例如 var list = new List();(未使用泛型)
* int i1 = (int)list[0]; 需要拆箱
*
* var list = new List<int>() 泛型定义为INT
* int l1 = list[0]l 不需要拆箱
*
* 其次,如果不设定泛型,第一个例子中的数组可以插入各种类型例如string 和类对象等
* 如果设定了泛型,数组就无法插入除开泛型以外的类型
*
* 命名规则,以T开头,如果只用了一个泛型参数,可以直接命名为T。
* 如public class list <T>
* -------------(简单理解,就是定义的时候,先一个T,作为一个标识符,到时候的时候再参照约束条件,确定写入类型)--------------
*
* 泛型方法
* 就是方法的模型,给定具体的类型,就可以实例化出一个操作该类的具体方法,泛型类中一般有泛型方法,普通类中也可以有泛型方法
*
* 约束,添加了约束,才能更加准确的调用方法,没有约束只能调用object的方法
* 约束的类型
* 类名 , class, struct ,接口名,new()
* 如果传入一个类,那就只能使用该类或者集成该类的派生类
* 如果传入一个class 那就说明可以是任何类
* 如果传入一个struct 说明可以传入任何值
* 如果传入的接口名,说明可以传入该接口类型或者任何实现该接口的类型
* 如果传入new(),说明可以传入带有 无参共有构造函数的类
* 约束规则
* A 主约束 B 接口约束 C 构造约束
* A 只能有一个,类名,class,struct
* B 能有任意多个
* 例如
* void cage<T>
* where T: Pet ,interface,new()
* 表示pet及其派生类,必须实现interface接口, 有默认构造函数
*
*
* 泛型接口
* 允许我们将接口成员的参数和返回类型设置为泛型
*
* interface Imyself<T>
* {
* T Myself(T self);
* }
*
* 协变与抗变
* 参数类型是协变得,如果有两个类,A派生自B,那么要求B类型的参数,可以填写A
* 方法类型是抗变得,如果一个方法返回 B, 那么返回类型只能是B ,不能是A,因为A 不一定是B,
* 但是如果一个方法返回是 A ,那么返回类型 可以为A也可以为B。
* 泛型接口使用OUT关键词就表示返回类型只能是T
* 如果使用IN关键字就表示T只能作为参数输入
*
*/
//代码示例
static void Main(string[] args)
{
//插入类
var dogCage = new Cage<Dog>(1);
dogCage.Putint(new Dog("a"));
dogCage.Putint(new Dog("b"));
var pet = dogCage.Takeout();
pet.printName();
//插入数字
var numCage = new Cage<int>(2);
numCage.Putint(5);
numCage.Putint(7);
numCage.Putint(9);
var nu = numCage.Takeout();
Console.WriteLine("take out "+nu.ToString());
//泛型方法举例 定义见dog类
var dog = new Dog("D");
dog.isHappy<person>(new person());
dog.isHappy<int>(6);
//泛型约束方法举例 定义见dog类
var dogE = new Dog("E");
dogE.isSad<Cat>(new Cat("Tom"));
//dogE.isSad<int>(8); //这里会报错,因为约束泛型只能是pet及其派生类
//泛型接口使用
Program gg = new Program();
gg.Act(new Dog("logan"));
gg.Act(new Cat("laola"));
}
//接口实现
public void Act(Dog pet)
{
pet.printName();
}
public void Act(Cat pet)
{
pet.printName();
}
}//泛型类
public class Cage<T>
{
T[] array;
readonly int Size;
int num;
public Cage(int n)
{
Size = n;
num = 0;
array = new T[Size];
}
public void Putint(T pet)
{
if (num < Size)
{
array[num++] = pet;
Console.WriteLine("get the pet");
}
else
{
Console.WriteLine("cage is full");
}
}
public T Takeout()
{
if (num > 0)
{
return array[--num];
}
else
{
Console.WriteLine("cage is empty");
return default(T);
}
}
}
//接口
public interface IDog<T> where T : Pet
{
void Act(T pet);
}
//pet 类
public class Pet
{
private string name;
public Pet(string name)
{
Name = name;
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
virtual public void speak()
{
Console.WriteLine("pet speaks");
}
virtual public void printName()
{
Console.WriteLine("My name is "+Name);
}
}
//继承自pet类的dog类
class Dog:Pet
{
public Dog(string name) : base(name)
{
Name = name;
}
public override void speak()
{
Console.WriteLine("Dog speaks wang wang");
}
//泛型方法
public void isHappy<T>(T target)
{
Console.WriteLine("Dog is happy to "+target.ToString());
}
//泛型方法+约束
public void isSad<T>(T target) where T: Pet
{
Console.Write("Dog is sad to ");
target.printName();
}
}
class Labrador : Dog
{
public Labrador(string name) : base(name)
{
Name = name;
}
}
//继承自pet类的cat类
class Cat:Pet
{
public Cat(string name) : base(name)
{
Name = name;
}
public override void speak()
{
Console.WriteLine("cat speaks miao miao");
}
}
代码可以在github上下载:https://github.com/lcxxxc/UWP_Readness
选择study_day3_part_two 的那一份
相关文章推荐
- 新手菜鸟学习C#的笔记总结 之泛型
- C#中泛型学习笔记
- C#回顾学习笔记三十五:泛型集合List
- c#学习笔记之泛型
- C#学习笔记三: C#2.0泛型 可控类型 匿名方法和迭代器
- [读书笔记]C#学习笔记四: C#2.0泛型 可控类型 匿名方法和迭代器
- C#学习笔记:泛型委托Action<T>和Fun<TResult>
- C#学习笔记-接口,集合与泛型
- C#学习笔记:泛型委托Action<T>和Fun<TResult>
- (转载)C#中泛型学习笔记
- [读书笔记]C#学习笔记七: C#4.0中微小改动-可选参数,泛型的可变性
- C#学习笔记之泛型委托
- C#学习笔记-泛型
- [读书笔记]C#学习笔记四: C#2.0泛型 可控类型 匿名方法和迭代器
- C# in Depth Third Edition 学习笔记-- C#2.0: 解决C#1.0的问题 1 泛型
- 精通C#:Chapter9 集合与泛型-学习笔记
- [读书笔记]C#学习笔记七: C#4.0中微小改动-可选参数,泛型的可变性
- [C#]C#学习笔记-接口,集合与泛型
- C#中泛型学习笔记
- [读书笔记]C#学习笔记四: C#2.0泛型 可控类型 匿名方法和迭代器