逆向性如何与.net核心中的Func委托一起使用

use*_*910 2 c# generic-variance .net-core asp.net-core-2.1

我有以下代码,我正在尝试为我的域对象编写通用验证规则.这样做我有一个问题来处理Func委托支持方差

public class Person { }
public class Employee : Person { }

internal interface IValidation<T> where T: Person  
{
     void AddValidationRule(Func<T,bool> predicateFunction);
}

internal class BaseValidation : IValidation<Person>
{
    void IValidation<Person>.RegisterValidationRules(Person person)
    {

    }
}

internal class EmployeeValidation : BaseValidation
{
    void RegisterValidation()
    {
        Func<Employee,bool> empPredicate = CheckJoiningDate;
        base.AddValidationRule(empPredicate);
    }

    bool CheckJoiningDate(Employee employee)
    {
        return employee.JoiningDate > DateTime.Now.AddDays(-1) ;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,编译器会给出一条错误消息

编译器错误在线:base.AddValidationRule(empPredicate); 参数1:无法从'System.Func <> Employee,bool>'转换为'System.Func <> Person,bool>

我曾参考过这个https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/dd465122%28v%3dvs.100%29但我仍然无法使编译器了解这里的逆变,

感谢您的帮助,让我更好地理解这一点

Eri*_*ert 8

你混淆了协方差和逆变.

使用协方差,泛型类型参数可以比所需的"更小".也就是说,如果我们有:

Func<Mammal, Mammal> f1 = whatever;
Func<Mammal, Animal> f2 = f1;
Run Code Online (Sandbox Code Playgroud)

为什么这样做? 在第二个参数中Func协变的.f2期待一个返回的代表Animal.它有一个返回较小类型的委托; 有少Mammal总比AnimalS,所以Mammal更小.

想想为什么会这样.当有人打电话给f2时,他们期待得到一只动物.但如果他们真的称之为f1,他们仍会得到一只动物,因为每只哺乳动物都是动物.

对于协方差,泛型类型的"大小" 在与类型参数的大小相同的方向上变化.Mammal小于Animal. Func<Mammal, Mammal>小于Func<Mammal, Animal>.这就是为什么它是"co"方差,co意思是"在一起".

逆变是相反的,因此是"反对",意思是"反对".对于逆变,泛型类型参数可能比预期更大:

 Func<Giraffe, Mammal> f3 = f1;
Run Code Online (Sandbox Code Playgroud)

f3需要一个长颈鹿的功能; 我们有一个更大型的哺乳动物.它更大,因为哺乳动物比长颈鹿更多.逆变说这很好,这应该是有道理的.如果有人用长颈鹿调用f3,那么如果这实际上是对f2的调用就可以,因为f2可以带长颈鹿; 它可以采取任何哺乳动物.

你混淆了协方差和逆变; 你期望逆变参数可以以协变的方式使用,这是错误的.雇员的职能无法转换为需要人员的职能,因为您可以将非雇员通过.需要员工的功能可以转换为需要经理的功能,因为所有经理都是员工.

  • @ user824910:函数的*输入*可以*更小*; 一个让人们可以接受任何员工的功能.但它们不能变得更大*; 只接受雇员的职能不能取任意人,因为该职能可能取决于非雇员中未找到的雇员财产. (2认同)