为什么这个 .NET class 不通过继承接受另一个父 class 作为类型参数?
Why does this .NET class not accept this other parent class as a type parameter via inheritance?
我想弄清楚为什么编译器会抱怨这个(我认为是一个简单的)继承场景:
鉴于此摘要class..
public class AbstractAnimalValidator<TAnimal> : AbstractValidator<TAnimal>
where TAnimal: Animal<IFoo, IBar>, new()
{
}
然后我尝试创建这个具体的 class...
public class CatValidator : AbstractAnimalValidator<Cat>{ }
我收到这个错误...
好的,那么 Cat
是什么?
public abstract class Animal<TFoo, TBar>
where TFoo : IFoo
where TBar : IBar { }
public class Cat : Animal<RedFoo, CleanBar> { }
我就是不明白:/猫是这两种类型......
现在this is the FULL REPO on .NET Fiddle展示一个实例。
更新 1:
我想我也要求的是
1. 为什么 我的代码不起作用? IE。我的大脑说这应该有效,但编译器说:given this scenario XXX .. I wouldn't know what to do ...
2.如何解决这个问题,所以我可以学习。
基本上,我已经多次阅读 covariance/contravariance 的内容,而且我的脑袋一直在爆炸……尤其是一些废话 foo/bar 的例子。希望通过我的 一点点具体 示例,我也许能够更深入地理解这一点。
这是因为 Cat
是 Animal<RedFoo, CleanBar>
的子类,AbstractAnimalValidator
期望是 Animal<IFoo, IBar>
的子类,但 Animal<RedFoo, CleanBar>
是 不是 Animal<IFoo, IBar>
的子类型,因此Cat
也不是子类型。
请注意,在此术语中,子类型是比子类更通用的术语。如果 B
继承 A
,B
是 A
的子类,如果 B
类型,B
是 A
的子类对象可以分配给 A
类型变量。
要解决此问题,请使 TFoo
和 TBar
类型参数 Covariant。这只允许用于C#中的接口,所以你需要引入一个新的接口:
public interface IAnimal<out TFoo, out TBar>
where TFoo : IFoo
where TBar : IBar { }
并像这样使用它:
public class AbstractAnimalValidator<TAnimal>
where TAnimal : IAnimal<IFoo, IBar>, new()
{
}
public abstract class Animal<TFoo, TBar> : IAnimal<TFoo, TBar>
where TFoo : IFoo
where TBar : IBar { }
这样Cat
就变成了IAnimal<IFoo, IBar>
的子类,因为RedFoo
是IFoo
的子类,而CleanBar
是[=34的子类=].
我想弄清楚为什么编译器会抱怨这个(我认为是一个简单的)继承场景:
鉴于此摘要class..
public class AbstractAnimalValidator<TAnimal> : AbstractValidator<TAnimal>
where TAnimal: Animal<IFoo, IBar>, new()
{
}
然后我尝试创建这个具体的 class...
public class CatValidator : AbstractAnimalValidator<Cat>{ }
我收到这个错误...
好的,那么 Cat
是什么?
public abstract class Animal<TFoo, TBar>
where TFoo : IFoo
where TBar : IBar { }
public class Cat : Animal<RedFoo, CleanBar> { }
我就是不明白:/猫是这两种类型......
现在this is the FULL REPO on .NET Fiddle展示一个实例。
更新 1:
我想我也要求的是
1. 为什么 我的代码不起作用? IE。我的大脑说这应该有效,但编译器说:given this scenario XXX .. I wouldn't know what to do ...
2.如何解决这个问题,所以我可以学习。
基本上,我已经多次阅读 covariance/contravariance 的内容,而且我的脑袋一直在爆炸……尤其是一些废话 foo/bar 的例子。希望通过我的 一点点具体 示例,我也许能够更深入地理解这一点。
这是因为 Cat
是 Animal<RedFoo, CleanBar>
的子类,AbstractAnimalValidator
期望是 Animal<IFoo, IBar>
的子类,但 Animal<RedFoo, CleanBar>
是 不是 Animal<IFoo, IBar>
的子类型,因此Cat
也不是子类型。
请注意,在此术语中,子类型是比子类更通用的术语。如果 B
继承 A
,B
是 A
的子类,如果 B
类型,B
是 A
的子类对象可以分配给 A
类型变量。
要解决此问题,请使 TFoo
和 TBar
类型参数 Covariant。这只允许用于C#中的接口,所以你需要引入一个新的接口:
public interface IAnimal<out TFoo, out TBar>
where TFoo : IFoo
where TBar : IBar { }
并像这样使用它:
public class AbstractAnimalValidator<TAnimal>
where TAnimal : IAnimal<IFoo, IBar>, new()
{
}
public abstract class Animal<TFoo, TBar> : IAnimal<TFoo, TBar>
where TFoo : IFoo
where TBar : IBar { }
这样Cat
就变成了IAnimal<IFoo, IBar>
的子类,因为RedFoo
是IFoo
的子类,而CleanBar
是[=34的子类=].