【发布时间】:2013-11-23 18:38:59
【问题描述】:
以下是我在一次测试中看到的一个问题,它提出了一些问题:
给定以下代码:
public delegate B func(B b);
public class A
{
public func x;
public int i = 2;
public A(int i) { this.i = i; x += f; }
public virtual C f(A a) { Console.WriteLine("C A.f(A)"); return new C(1); }
public virtual A f(C c) { Console.WriteLine("A A.f(C)"); return new A(2); }
}
public class B: A{
public B(int i) : base(i) { x += f; }
public virtual B f(B b) { Console.WriteLine("B B.f(B)"); return new B(3); }
public new C f(A a) { Console.WriteLine("C B.f(A)"); return new C(4); }
}
public class C: B{
public C(int i) : base(i) { x += f; }
public new B f(B b) { Console.WriteLine("B C.f(B)"); return new C(5); }
public override A f(C c) { Console.WriteLine("A C.f(C)"); return new A(6); }
}
有以下主要内容:
static void Main(string[] args)
{
C c = new C(12);
A a = c.x(c);
Console.WriteLine(a.i);
}
- 输出是什么?
- 如果我们将委托定义更改为:
public delegate C func(B b);,会发生什么情况 - 当我们将委托定义更改为
public delegate T func<T,U>(U u);并将 A 中的x更改为public func<B,B> x;时会发生什么?
官方的回答是:
到#1:
C A.f(A)
B B.f(B)
B C.f(B)
5
到#2:
它不会编译,因为在 B 类和 C 类中添加到 x 的方法是根据参数的静态类型选择的。所以在B类中需要添加B B.f(B)但返回类型不匹配,在C类中需要添加B C.f(B)但返回类型不匹配。
到#3:
它打印出与 #1 相同的答案,因为这两个定义是等价的。
这是我不明白的:
- 如何从所有重载选项中选择在
x+=f;行中添加到x的方法?具有与“this”的动态类型“最接近”的参数类型的重载方法是否被选中? - 除非用
in和out声明,否则泛型委托不是非变体吗?第 3 点的答案有何意义?
【问题讨论】:
标签: c# generics delegates covariance contravariance