泛型

泛型

  1. C#泛型的in, out关键字与Java中的?通配符解决了:如果B是A的子类,则C<A>与 C<B> 是否具有子类型化的关系。
  2. Object[] a = new SubClass[10];没有编译时错误,如果有,那么各种泛型数据结构将不能实现。
  3. C#中in, out关键字用于接口和委托,在定义泛型时就决定了逆变协变关系。Java则是在使用时通过指定super,extends关键字结合通配符{?}来决定逆变协变关系。
  4. 记住一点:C<A>与 C<B>之间是否具有协变或者逆变的关系。
  5. C# is declaration-site variance, java is use-site variance. C#是声明处型变,Java是使用处型变。

    kotlin兼具声明处型变及使用处型变

  6. 助记表
生产者消费者
返回值参数
PECS
OUTIN
协变逆变

C# 代码

public class Person { }

public class Student : Person { }

public class LittleStudent : Student { }

public delegate void Action<in T>(T obj);

public void test()
{
	List<Student> students = new List<Student>();
	
	Action<Person> pAction = (item) => { };
	Action<Student> sAction = p;
	Action<LittleStudent> lAction = (item) => { };
	
	// 正确:Action<Person>可以安全的转换为Action<Student>。
	// Action<in T> 对T具有逆变安全性。
	students.ForEach(pAction);
	
	// 正确
	students.ForEach(sAction);
	
	// 编译时错误,原因如下:
	// 假定可以通过编译:lAction接受的是LittleStudent,而现在传入的是Student.
	// 显然Student不能安全的转换为LittleStudent
	students.ForEach(lAction);
}

Java 代码


public class Person { }

public class Student extends Person { }

public class LittleStudent extends Student { }

//////////////////// 定义END ///////////////////////////

public void test() {
	List<Student> students = new ArrayList<Student>();
	List<? extends Student> y = students;
	
	Consumer<Person> p = (item) -> {};
	Consumer<? super Student> c = p;
	
	students.forEach(p);
	students.forEach(c);
	
	y.forEach(c);
	y.forEach(p);
	
	List<? super Student> superStudents = new ArrayList<Person>();
	
	// 编译时错误
	superStudents.forEach(p);
	// 编译时错误
	superStudents.forEach(c);
	
	Consumer<Object> o = (item)->{};
	// 正确
	superStudents.forEach(o);
}

C#协变与逆变

.NET 4.0中的泛型协变和反变

  1. 如果接口要支持对T逆变,那么接口中方法的参数类型都必须支持对T协变才行。这就是方法参数的协变-逆变互换原则。
  2. 如果一个接口需要支持对T进行协变或逆变,那么这个接口所有方法的返回值类型必须支持对T同样方向的协变或逆变。这就是方法返回值的协变-逆变一致原则

Kotlin中泛型的支持

英文文档
中文文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值