我有以下对象和类的设计。如方法 Play(Animal a)
的注释中所述,我希望能够测试a
是否有效属于 Cat<Big>
类型并相应地强制a
,以便我可以MethodUniqueToCats()
访问该方法。
我能够通过a.GetType().GetGenericArguments()[0]
获得Big
。但是,不知何故,我未能在如何从Animal
到Cat<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)
}
除非你绝对必须这样做,否则我个人不会这样做。我会在这里避免反射,即我会添加接口ICat
和IDog
并尝试在您的方法中强制转换为它。