如何将通过接口标识的对象强制转换为实现该接口的 Generic 类的特定对象



我有以下对象和类的设计。如方法 Play(Animal a) 的注释中所述,我希望能够测试a是否有效属于 Cat<Big> 类型并相应地强制a,以便我可以MethodUniqueToCats()访问该方法。

我能够通过a.GetType().GetGenericArguments()[0]获得Big。但是,不知何故,我未能在如何从AnimalCat<Big>方面实现飞跃.我相信这是可能的,因为Visual Studio能够在运行时确定此信息(通过方法Play(Animal a)内的调试+断点进行检查(。

interface Animal
{
}
class Cat<T> : Animal
{
    public void MethodUniqueToCats()
    {
    }
}
class Dog<T> : Animal
{
}
class Freetime
{
    private Animal my_animal;
    public void Play(Animal a)
    {
        my_animal = a;
        Type t = a.GetType().GetGenericArguments()[0];
        // I would like to test if the type of 'a' passed to this 
        // method is a Cat and subsequently cast it to a Cat of type 't'
        // so that I can access 'MethodUniqueToCats()'.
        // Line below does not work but wondering how to go about:
        // if (a.GetType().IsAssignableFrom(typeof(Cat<t>))
        // How to do the 'casting'
    }
}
class MyProgram
{
    public static void Main(string[] args)
    {
        Freetime f = new Freetime();
        Cat<Big> c = new Cat<Big>();
        f.Play(c);
    }
}

提前谢谢。

如果你绝对想这样做(并且违反了 Liskov 替换原则(,那么最简单的方法是使用 Cat 接口,如下所示:

interface IAnimal
{
}
interface ICat
{
    void MethodUniqueToCats();
}
class Cat<T> : IAnimal, ICat
{
    public void MethodUniqueToCats()
    {
    }
}

现在你可以像这样测试你的对象是一只猫:

IAnimal animal = new Cat<int>();
var cat = animal as ICat;
if (cat != null)
{
    cat.MethodUniqueToCats();
}

或者,如果你足够幸运地运行C# v7(即Visual Studio 2017(,你可以这样做:

if (animal is ICat cat)
{
    cat.MethodUniqueToCats();
}

这个怎么样?

 if (a.GetGenericTypeDefinition() == typeof(Cat<>))
    {
       a.GetMethod("MethodUniqueToCats").Invoke(null, null)
    }

除非你绝对必须这样做,否则我个人不会这样做。我会在这里避免反射,即我会添加接口ICatIDog并尝试在您的方法中强制转换为它。

最新更新