1,泛型接口和委托的逆变与协变
核心:
类型转换,参数只应用于引用类型
2,关键字:协变,out
Foo<父类>=Foo<子类>
Ioo<父类>=Ioo<子类>
3,关键字:逆变,in
Foo<子类>=Foo<父类>
Ioo<子类>=Ioo<父类>
返回值协变和参数逆变
//泛型委托
delegate T NormalEventHandler<T>(T t);
//delegate T CovarianceEventHandlerError<out T>(T tOut);//Error错误 1 方差无效: 类型参数“T”必须为“Test.CovarianceEventHandlerError<T>.Invoke(T)”上有效的 逆变式。“T”为 协变。
delegate T CovarianceEventHandler<out T>();
//delegate T ContravarianceEventHandlerError<in T>(T tIn);//Error错误 1 方差无效: 类型参数“T”必须为“Test.ContravarianceEventHandlerError<T>.Invoke(T)”上有效的 协变式。“T”为 逆变
delegate void ContravarianceEventHandler<in T>(T tIn);
delegate T2 ContravarianceEventHandler<in T1,out T2>(T1 tIn);
//泛型接口
interface INormal<T> { };
interface ICovariance<out T> { };
interface IContravariance<out T> { };
class ParentClass
{
//基类,父类
public void Fun()
{
MessageBox.Show("ParentClass");
}
}
class ChildClass : ParentClass
{
//派生类,子类
public void Fun()
{
MessageBox.Show("ChildClass");
}
public void Fun(int i)
{
MessageBox.Show("IIII--ChildClass");
}
}
public partial class Form1 : Form
{
//协变
CovarianceEventHandler<ParentClass> CovarianceParent = null;
CovarianceEventHandler<ChildClass> CovarianceChild = null;
//逆变
ContravarianceEventHandler<ParentClass> ContravarianceParent = null;
ContravarianceEventHandler<ChildClass> ContravarianceChild = null;
ParentClass ParentFun()
{
ParentClass p = new ParentClass();
p.Fun();
return p;
}
ChildClass ChildFun()
{
ChildClass c = new ChildClass();
c.Fun(0);
return c;
}
void ParentFun(ParentClass p)
{
p.Fun();
}
void ChildFun(ChildClass c)
{
c.Fun(0);
}
public Form1()
{
InitializeComponent();
//协变-父=子
CovarianceParent = ParentFun;
CovarianceChild = ChildFun;
CovarianceParent = CovarianceChild;
//CovarianceChild = CovarianceParent;//Error,类型无法转换
ParentClass obj = CovarianceParent();
ChildClass obj1 = CovarianceChild();
//ChildClass obj2 = CovarianceParent();//Error,类型无法转换
if (obj is ChildClass && obj1 is ChildClass)
{
MessageBox.Show("success");
}
if (obj is ParentClass && obj1 is ParentClass)
{
MessageBox.Show("fail");
}
obj.Fun();
obj1.Fun();
//obj2.Fun();
//逆变-子=父
ContravarianceParent = ParentFun;
ContravarianceChild = ChildFun;
ContravarianceChild = ContravarianceParent;
//ContravarianceParent = ContravarianceChild;//Error,类型无法转换
ContravarianceChild(new ChildClass());
ContravarianceParent(new ParentClass());
}