首先我们都知道父类对象可以指向子类对象
class Document
{
}
class OperationGuide:Document
{
}
那么就可以写成 Document doc = new OperationGuide();
但如果用于泛型就不行了,例如我写一个泛型类Test,那么就不能这样写了,会报一个隐士转换错误,
Test<Document> doc = new Test<OperationGuide>();
那么此时泛型的协变和抗变就出现了,协变和抗变只能用在泛型委托和泛型接口上和值类型或引用类型上,,主要是对象参数和返回值的类型进行转换。
1.泛型接口的协变
如果泛型类型out关键字标注,那么该泛型接口就是协变,也就意味着返回类型只能是T
interface IDocument<out T>
{
string Title { get; set; }
string Content { get; set; }
}
{
string Title { get; set; }
string Content { get; set; }
}
class Test:IDocument<OperationGuide>
{
private string title;
private string content;
public string Title
{
get { return title; }
set { title = value; }
}
public string Content
{
get { return content; }
set { content = value; }
}
private static Test test;
public static Test GetTest
{
get { return test = new Test(); }
}
}
{
private string title;
private string content;
public string Title
{
get { return title; }
set { title = value; }
}
public string Content
{
get { return content; }
set { content = value; }
}
private static Test test;
public static Test GetTest
{
get { return test = new Test(); }
}
}
class Program
{
static void Main(string[] args)
{
IDocument<OperationGuide> oper = Test.GetTest;
IDocument<Document> doc = oper;
}
}
{
static void Main(string[] args)
{
IDocument<OperationGuide> oper = Test.GetTest;
IDocument<Document> doc = oper;
}
}
因为接口是协变,所以可以把返回值oper赋予doc变量
2.泛型接口的抗变
如果泛型类型用int关键字标注,泛型接口就是抗变,这样,接口只能把泛型类型T用做其方法的输入
interface IDocument<in T>
{
void ShowInfo(T docInfo);
}
{
void ShowInfo(T docInfo);
}
class Display : IDocument<Document>
{
public void ShowInfo(Document doc)
{
Console.WriteLine("我是文档父类"+doc.ToString());
}
}
{
public void ShowInfo(Document doc)
{
Console.WriteLine("我是文档父类"+doc.ToString());
}
}
class Program
{
static void Main(string[] args)
{
OperationGuide operation = new OperationGuide();
IDocument<Document> doc = new Display();
IDocument<OperationGuide> oper = doc;
oper.ShowInfo(operation);
}
}
{
static void Main(string[] args)
{
OperationGuide operation = new OperationGuide();
IDocument<Document> doc = new Display();
IDocument<OperationGuide> oper = doc;
oper.ShowInfo(operation);
}
}
首先实例化一个子对象文档类,接着就创建一个Display实例赋予doc变量,因为IDocument是抗变,所以可以把结果赋予泛型子对象变量oper。
简单的理解泛型接口或委托的协变就是将子对象到父对象的转换,而抗变就是父对象到子对象的转换
转载请注明出处:http://blog.csdn.net/wu5101608/article/details/30707643
AT:Coyote 知识正在蔓延