C#接口协变不懂

Tony_Xian 2017-08-31 12:39:57
using System;
namespace test
{
class Animal { public string Name;}
class Dog : Animal { }

interface IMyIfc<out T>
{
T GetFirst();
}

class SimpleReturn<T> : IMyIfc<T>
{
public T[] items = new T[2];
public T GetFirst() { return items[0]; }
}
class Program
{
static void Dosomething(IMyIfc<Animal> returner)
{
Console.WriteLine(returner.GetFirst().Name);
}
static void Main()
{
SimpleReturn<Dog> dogReturner = new SimpleReturn<Dog>();
dogReturner.items[0] = new Dog() { Name = "Avonlea" };
IMyIfc<Animal> animalReturner = dogReturner;
Dosomething(dogReturner);
Console.ReadKey();
}
}
}


IMyIfc<Animal> animalReturner = dogReturner;
Dosomething(dogReturner);

这两句代码不懂,第一句为什么能把类赋值给接口,请各位大神两句都解释下,谢谢
...全文
270 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
高冷技术宅 2017-09-02
  • 打赏
  • 举报
回复
IMyIfc<Animal> animalReturner = dogReturner; 这行代码对于你目前的成序来说是没什么用的 只是子类对象写变为父类对象 你是不理解为什么输出的还是狗的名字对吗? 父类对象可以指向子类对象,所以子类对象作为参数不会出现变异错误,但在运行时它还是一个dog对象,所以运行接过还是dog的名字
正怒月神 2017-08-31
  • 打赏
  • 举报
回复
这里先不讨论为何out只能作为输出结果,in只能作为入参的问题。 只是纯粹讨论我理解的out和in的作用
正怒月神 2017-08-31
  • 打赏
  • 举报
回复
我说一下我的理解:
协变---子类泛型转变为父类泛型
逆变---父类泛型转换为子类泛型

static void Main()
{
//例子1
T1 t1 = new T1();
T2 t2 = new T2();
t1 = t2;
//例子2
ITest<T1> it1 = null;
ITest<T2> it2=null;
it1 = it2;



Console.ReadKey();
}

//out 关键字
public interface ITest<out T>
{}
public class T1
{ }

public class T2:T1
{ }


例子1
T2可以直接转换为T1 这个不解释了。

例子2
为何 没有out关键字, it1 = it2;就报错?
我理解是,在面向对象的思想里,虽然 T1和T2有继承关系。但是

ITest<T1> ITest<T2>并没有直接的继承关系,只是内部元素具有继承关系。
因此为了省去其中的转换步骤,出现了out和in的关键字。方便泛型集合的转换
  • 打赏
  • 举报
回复
嗯,一个 SimpleReturn<Dog> 对象就是一个 IMyIfc<Dog> 对象,这确实跟协变没有直接关系。然后 Dog 是一个 Animal(你缺少这段代码说明),这里才跟协变产生了关系。
  • 打赏
  • 举报
回复
一个 SimpleReturn<Dog> 对象就是一个 IMyIfc<T> 对象,这确实跟协变没有直接关系。
xdashewan 2017-08-31
  • 打赏
  • 举报
回复
接口引用指向继承了接口的子类对象,这好像没什么疑问吧

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧