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但我仍然无法使编译器了解这里的逆变,
感谢您的帮助,让我更好地理解这一点
你混淆了协方差和逆变.
使用协方差,泛型类型参数可以比所需的"更小".也就是说,如果我们有:
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可以带长颈鹿; 它可以采取任何哺乳动物.
你混淆了协方差和逆变; 你期望逆变参数可以以协变的方式使用,这是错误的.雇员的职能无法转换为需要人员的职能,因为您可以将非雇员通过.需要员工的功能可以转换为需要经理的功能,因为所有经理都是员工.
| 归档时间: |
|
| 查看次数: |
217 次 |
| 最近记录: |