0

关于协变和逆变的方法委托之间的隐式转换在 C# 中实现的方式,我有几个问题。

delegate void ImplicitFunction<T>(T thing);
delegate void ExplicitFunction<in T>(T thing);
delegate void AnimalFunction(Animal thing);
delegate void DogFunction(Dog thing);

static void Process<T>(T thing) {
    // ...
}
static void AnimalProcess(Animal thing) {
    // ...
}

static void Main() {

据我了解,方差处理对于将函数分配给不同的委托是隐含的,即:

    ImplicitFunction<Dog> processObject = Process<Animal>;

(从概念上讲,虽然可能不是语义上的,但我相信这是逆变。当然,如果我的任何假设完全错误,我将不胜感激。)经过数小时的仔细研究,我相信我完全理解它是如何工作的以及为什么. 但我也了解到,我无法将方法从一种类型(委托)转换为另一种,即使它为相同的类型分配了相同的值,只需两个步骤:

    ImplicitFunction<Animal> tempProcessor = Process<Animal>;
    ImplicitFunction<Dog> processDogConv = tempProcessor; // compile error

问题1:为什么不呢?并且请不要说“因为你不使用'in'”或“因为它不是泛型类型”。我想知道这种行为的理由是什么,就像在某些情况下为了防止传递无效类型而设置了方差限制一样。现在,我还了解到 C# 支持使用关键字“in”和“out”进行显式委托转换。像这样:

    ExplicitFunction<Animal> processAnimal = Process<Animal>;
    ExplicitFunction<Dog> processDog = processAnimal;

但是没有泛型我不能做同样的事情:

    AnimalFunction processAnimalNonGeneric = AnimalProcess;
    DogFunction processDogNonGeneric = processAnimalNonGeneric; // compile error

我有一种感觉,其原因可能与不支持隐式方差转换的原因密切相关。

问题2:但是为什么?为什么我不能像这样使用'in'关键字:

delegate void AnimalFunction(in Animal thing);
delegate void DogFunction(in Dog thing);

再一次,我知道这不是它的工作原理,但是排除此功能的理论上的“我们不能因为如果有人做了这个”的原因是什么?

}

PS 这段代码已经编译以确保它的行为与我描述的一样,并且只需要一个包装类和两个空Dog : Animal类。

4

0 回答 0