当我尝试定义这样的变量时:
IVeterinarian<IAnimal> v = (IVeterinarian<IAnimal>)new CatVeterinarian();以下是接口和类解密的例子:
interface IAnimal
{
}
class Dog : IAnimal
{
}
class Cat : IAnimal
{
}
interface IVeterinarian<TAnimal> where TAnimal : IAnimal
{
void Heal(TAnimal animal);
}
class DogVeterinarian : IVeterinarian<Dog>
{
public void Heal(Dog animal)
{
}
}
class CatVeterinarian : IVeterinarian<Cat>
{
public void Heal(Cat animal)
{
}
}我的例子和在对象变量的IEnumerable中声明字符串的IEnumerable有什么区别?
为什么我要拿到InvalidCastException。
有什么想法吗?
发布于 2018-01-12 19:44:37
你不能创建这样一个实例;
IVeterinarian v = (IVeterinarian)new CatVeterinarian();因为,您应该传递一个从IAnimal实现的类型;
IVeterinarian<Cat> v = new CatVeterinarian();编辑
由于IVeterinarian<IAnimal>不是IVeterinarian<Cat>,甚至没有实现它,所以您将被强制转换为无效异常。
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}正如您所看到的,IEnumerable使用out参数并使其成为协变量。请回顾一下这个页面。
在您的情况下,您不能使您的泛型作为协变,因为泛型被用作签名。通过使用协变量,您可以返回问题中提到的派生类型。
IEnumerable<object> list = new List<string>();简而言之,它与你想要尝试的案例有不同的目的。
发布于 2018-01-12 21:27:36
在我的使用中,我想要照顾不同的每一个动物。我找到了一个简单的方法--这是我的解决方案:
下面是一个例子:
interface IAnimal
{
}
class Dog : IAnimal
{
}
class Cat : IAnimal
{
}
interface IVeterinarian
{
void Heal(IAnimal animal);
}
abstract class BaseVeterinarian<T> : IVeterinarian
where T : IAnimal
{
public void Heal(IAnimal animal)
{
Heal((T)animal);
}
protected abstract void Heal(T animal);
}
class DogVeterinarian : BaseVeterinarian<Dog>
{
protected override void Heal(Dog animal)
{
}
}
class CatVeterinarian : BaseVeterinarian<Cat>
{
protected override void Heal(Cat animal)
{
}
}请注意,您必须发送一个正确的IAnimal对象作为参数--否则它会抛出一个InvalidCastException。
现在,我可以使用不同的实现来创建IVeterinarian对象,就像我在问题中所提出的那样。
IVeterinarian v = new CatVeterinarian();
v.Heal(new Cat());
IVeterinarian v2 = new DogVeterinarian();
v2.Heal(new Dog());https://stackoverflow.com/questions/48233004
复制相似问题