The covariance and contra-variance of C#
using System;
using System.Collections;
using System.Collections.Generic;
namespace C_exercise
{
class Mankind
{
}
class Chinese: Mankind
{
}
class MainClass
{
publicstatic void Display(Mankind Someone)
{
}
publicstatic Chinese GetChinese()
{
Chinese Lee =new Chinese ();
return Lee;
}
publicstatic Mankind GetMankind()
{
Mankind Jim =new Mankind ();
return Jim;
}
publicstatic void Main(string[] args)
{
//例一,参数类型的协变
var Liu =new Chinese ();
Display (Liu); //正确,Liu不只是中国人,同时也是人类。方法的参数类型的派生类型都可变为此方法的
//参数类型,但它的基类型无法变为它的参数类型。
//例二,方法的返回类型的抗变
Mankind TheStranger = GetChinese (); //正确,中国人一定是人类。
Chinese AnotherStranger = GetMankind ();//错误,返回的人是不确定国籍的,不一定是中国人。方法的返回类型的所有基类都可
//以变为此方法的返回类型,但它的派生类型无法变为它的返回类型。
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
.NET 4.0 泛型接口的协变
using System;
using System.Collections;
using System.Collections.Generic;
/// The covariance and contravariance of C#
namespace C_exercise
{
public interface IBorn<out T> //协变,泛型类型用out关键字标注,返回类型必须是T
{
T Born{get;}
}
class Mankind
{
}
class Chinese: Mankind
{
}
class ChineseBorn:IBorn<Chinese>
{
private Chinese Baby=new Chinese();
public Chinese Born
{
get
{
return Baby;
}
}
}
class MankindBorn:IBorn<Mankind>
{
private Mankind Baby=new Mankind();
public Mankind Born
{
get
{
return Baby;
}
}
}
class MainClass
{
//IBorn<Chinese> Zhang=new ChineseBorn(); //正确.
//IBorn<Mankind> Zhang=new ChineseBorn(); //正确,Zhang具有人类新生儿接口,可成为中国新生儿
//IBorn<Mankind> Zhang=new MankindBorn(); //正确
//IBorn<Chinese> Zhang=new MankindBorn(); //错误,Zhang只有中国新生儿接口,无法被赋予人类新生儿的所有内容。
//泛型接口的协变:所有泛型接口类型的派生类型对象都可以变为此泛型接口类型的对象,
publicstatic void Main(string[] args) //但它的基类型对象无法变为此泛型接口类型的对象。
{
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
.NET 4.0 泛型接口的抗变
using System;
using System.Collections;
using System.Collections.Generic;
/// The covariance and contravariance of C#
namespace Cexercise
{
publicinterface ICheck<in T> //抗变,in关键字标注,接口内方法输入类型必须为T
{
void State(T Someone);
}
class Mankind
{
}
class Chinese: Mankind
{
}
class MankindCheck:ICheck<Mankind>
{
publicvoid State(Mankind Someone)
{
Console.WriteLine ("Nation,Sex,Age");
}
}
class ChineseCheck:ICheck<Chinese>
{
publicvoid State(Chinese Someone)
{
Console.WriteLine ("Sex,Age");
}
}
class MainClass
{
publicstatic void Main(string[] args)
{
//ICheck<Mankind> HumanState = new MankindCheck (); //
//ICheck<Chinese> ChineseState = HumanCheck; //正确,人类检测实现了人类检测接口可以满足一切中国人检测的内容
ICheck<Chinese> ChineseState =new ChineseCheck (); //
ICheck<Mankind> MankindState = ChineseCheck;//错误,中国人检测接口无法满足人类检测接口的所有内容。
//泛型接口的抗变:所有泛型接口类型的基类的对象都可以变成此泛型
//接口的对象,但它的派生类型的对象无法变为此泛型接口类型的对象
}
}
}