c#参考理解?

时间:2012-02-03 21:43:05

标签: c# .net-4.0 covariance

如果我有:

   public class A {   public int a1;}
   public class B : A {  public int b1;}

   void myFunc(A a) 
   {}

  static void Main(string[] args)
       {
         B b = new B();
         myFunc(b);
       }
<{1>}中的

myFunc可以访问a个对象,但它只能引用(无需强制转换)内存中b的区域。

这是理解的。

协方差中,似乎type A也可以访问aenter image description here

正如您所看到的 - 它接受b的可枚举,并且仍然可以访问其A类型的对象


的问题:

1 )好的,幕后工作如何? B引用如何向我显示A对象?

2 )如果我想在函数中看到larger类的a1属性,该怎么办?

修改

协方差相关:

  

在C#4之前,你无法传递List:       无法转换        'System.Collections.Generic.List'到        'System.Collections.Generic.IEnumerable'

Covariance and contravariance real world example

3 个答案:

答案 0 :(得分:6)

  

A引用如何能够向我显示更大的对象?

首先,它是较小的类型。每只长颈鹿都是动物,但不是每只动物都是长颈鹿。因此,世界上长颈鹿的数量比世界上的动物少。因此,长颈鹿是一种比动物更小的类型。

您的类型B是较小的类型而不是A.当然,对较大类型的引用可以引用较小类型的内容。

这与协方差无关。 IEnumerable<A>始终可以为您提供B

List<A> myList = new List<A>() { new B(); } // No covariance here
Console.WriteLine(myList[0].GetType()); // it's a B.

动物名单中可以包含长颈鹿。这与协方差无关。

同样,引用总是可以为您提供较小的类型:

A a = new B(); // Legal!
  那些说它与协方差无关的人......

A的序列包含 a B与协方差无关。与协方差有关的是 B序列可以通过引用转换转换为A序列。在将协变转换添加到C#4之前,该转换将失败。

  

如果我想在函数中看到A类的a1属性怎么办?我应该改变什么?

你不应该改变任何东西;它已经有效了。试试吧。

答案 1 :(得分:5)

  

如您所见 - 它接受A的Enumerable,它仍然可以访问其B类型的对象

调试器将其显示为B,因为它看到它的实际类型是B. myFunc中的代码只能访问A的成员,除非它将对象强制转换为B.

答案 2 :(得分:0)

myFunc会看到类型B,因为您使用myFunc(b);

中的一个来调用它

你在基类A中看到a1

如果你这样做

static void Main(string[] args)
       {
         A a = new A();
         myFunc(a);
       }

你会直接看到A型

修改

为了说清楚:

void myFunc(A a) 

应该读作

void myFunc({Either A or something "larger" than A} a) 

“较大”意味着“继承”