我有以下对象和类的设计。正如方法Play(Animal a)
的评论中所述,我希望能够测试a
实际上是Cat<Big>
类型并相应地转换a
以便我可以访问方法MethodUniqueToCats()
。
我可以通过Big
获得a.GetType().GetGenericArguments()[0]
。但是,不知何故,我没有实现如何从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);
}
}
提前致谢。
答案 0 :(得分:0)
这个怎么样?
if (a.GetGenericTypeDefinition() == typeof(Cat<>))
{
a.GetMethod("MethodUniqueToCats").Invoke(null, null)
}
除非你绝对必须,否则我不会亲自去做。
我会在这里避免反思,即我会添加接口ICat
和IDog
并尝试在你的方法中强制转换它。
答案 1 :(得分:0)
如果您绝对想这样做(并违反Liskov Substitution Principle),那么最简单的方法就是使用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();
}