C# 类型接口的铸造变量<;TChild>;接口<;t租金>;

C# 类型接口的铸造变量<;TChild>;接口<;t租金>;,c#,C#,当我尝试定义这样的变量时: IVeterinarian<IAnimal> v = (IVeterinarian<IAnimal>)new CatVeterinarian(); IVeterinarian v=(IVeterinarian)新猫兽医(); 以下是接口和类的减容示例: interface IAnimal { } class Dog : IAnimal { } class Cat : IAnimal { } interface IVeterinaria

当我尝试定义这样的变量时:

IVeterinarian<IAnimal> v = (IVeterinarian<IAnimal>)new CatVeterinarian();
IVeterinarian v=(IVeterinarian)新猫兽医();
以下是接口和类的减容示例:

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)
    {
    }
}
接口IAnimal
{
}
班犬:IAnimal
{
}
类别:IAnimal
{
}
接口IVeterinarian,其中TAnimal:IAnimal
{
空洞愈合(坦尼玛动物);
}
班级兽医:IVeterinarian
{
公共空间治疗(狗和动物)
{
}
}
兽医:兽医
{
公共空间治疗(猫科动物)
{
}
}

我的例子和在IEnumerable of objects变量中声明IEnumerable of strings有什么区别

为什么我会得到一个无效的例外


有什么想法吗?

你不能创建这样的实例

IVeterinarian v = (IVeterinarian)new CatVeterinarian();
因为,您应该传递一个从
IAnimal
实现的类型

IVeterinarian<Cat> v = new CatVeterinarian();

简而言之,它与您想要尝试的案例有不同的目的。

您不能创建这样的实例

IVeterinarian v = (IVeterinarian)new CatVeterinarian();
因为,您应该传递一个从
IAnimal
实现的类型

IVeterinarian<Cat> v = new CatVeterinarian();

简而言之,它与您想要尝试的案例有不同的目的。

在我的案例中,我想以不同的方式照顾每只动物。我找到了一个简单的方法-以下是我的解决方案:

  • 从iVerterinarian中删除泛型
  • 创建一个实现IVeterinarian的泛型基础Veterinarian类,其中T实现IAnimal
  • 在基类中创建一个抽象方法,其名称与获取T类型动物参数的名称相同
  • 通过调用抽象方法来实现原始的Heal方法,该方法在将动物参数转换为T之后给出动物参数
  • 在猫狗兽医类中,只需重写抽象方法
  • 下面是一个例子:

    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)
        {
        }
    }
    

    在我的用例中,我想以不同的方式照顾每只动物。我找到了一个简单的方法-以下是我的解决方案:

  • 从iVerterinarian中删除泛型
  • 创建一个实现IVeterinarian的泛型基础Veterinarian类,其中T实现IAnimal
  • 在基类中创建一个抽象方法,其名称与获取T类型动物参数的名称相同
  • 通过调用抽象方法来实现原始的Heal方法,该方法在将动物参数转换为T之后给出动物参数
  • 在猫狗兽医类中,只需重写抽象方法
  • 下面是一个例子:

    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)
        {
        }
    }
    

    IVeterinarian
    没有在任何地方声明,只有通用版本。当然你会出错:)既然兽医是兽医,为什么还要投呢?没有必要强制转换它…
    CatVeterinarian
    实现
    IVeterinarian
    而不是
    IVeterinarian
    。我的示例与在IEnumerable of objects变量中声明字符串的IEnumerable有什么区别?
    IEnumerable
    T
    中是协变的,而您的
    IVeterinarian
    则不是。它也不能是协变的,因为它允许您调用
    v.Heal(new Dog())
    ,这将破坏类型安全,因为
    CatVeterinarian.Heal
    需要一个
    Cat
    参数。
    IVeterinarian
    没有在任何地方声明,只有通用版本。当然你会出错:)既然兽医是兽医,为什么还要投呢?没有必要强制转换它…
    CatVeterinarian
    实现
    IVeterinarian
    而不是
    IVeterinarian
    。我的示例与在IEnumerable of objects变量中声明字符串的IEnumerable有什么区别?
    IEnumerable
    T
    中是协变的,而您的
    IVeterinarian
    则不是。它也不能是协变的,因为它允许您调用
    v.Heal(new Dog())
    ,这将破坏类型安全,因为
    CatVeterinarian.Heal
    需要
    Cat
    参数。但是Cat继承了IAnimal,为什么它不同于在IEnumerable of objects变量中声明IEnumerable of string?谢谢。我还添加了我使用的解决方案,但是cat继承了IAnimal,为什么它不同于在IEnumerable of objects变量中声明IEnumerable of strings?谢谢。我还添加了我使用的解决方案