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());
}