C# 如何将通过接口标识的对象强制转换为实现该接口的泛型类的特定对象
我有以下对象和类的设计。如方法C# 如何将通过接口标识的对象强制转换为实现该接口的泛型类的特定对象,c#,generics,casting,C#,Generics,Casting,我有以下对象和类的设计。如方法Play(Animal a)的注释所述,我希望能够测试a是否有效地属于Cat类型,并相应地铸造a,以便我可以访问方法MethodUniqueToCats() 我可以通过a.GetType().GetGenericArguments()[0]获得Big。但是,不知何故,我未能在如何从动物到猫的问题上实现飞跃。我相信这是可能的,因为Visual Studio能够在运行时确定此信息(通过方法Play(Animal a)中的调试+断点进行检查) 界面动物 { } 类别猫:动
Play(Animal a)
的注释所述,我希望能够测试a
是否有效地属于Cat
类型,并相应地铸造a
,以便我可以访问方法MethodUniqueToCats()
我可以通过a.GetType().GetGenericArguments()[0]
获得Big
。但是,不知何故,我未能在如何从动物
到猫
的问题上实现飞跃。我相信这是可能的,因为Visual Studio能够在运行时确定此信息(通过方法Play(Animal a)
中的调试+断点进行检查)
界面动物
{
}
类别猫:动物
{
公共无效方法唯一目录()
{
}
}
狗类:动物
{
}
课余时间
{
私人动物我的宠物;
公共虚空游戏(动物a)
{
我的动物=a;
类型t=a.GetType().GetGenericArguments()[0];
//我想测试“a”的类型是否传递给此
//方法是一个Cat,然后将其强制转换为“t”类型的Cat
//这样我就可以访问“MethodUniqueToCats()”。
//下面的行不起作用,但想知道如何进行:
//if(a.GetType().IsAssignableFrom(typeof(Cat))
//如何进行“铸造”
}
}
类MyProgram
{
公共静态void Main(字符串[]args)
{
空闲时间f=新空闲时间();
Cat c=新Cat();
f、 游戏(c);
}
}
提前谢谢。这个怎么样
if (a.GetGenericTypeDefinition() == typeof(Cat<>))
{
a.GetMethod("MethodUniqueToCats").Invoke(null, null)
}
if(a.GetGenericTypeDefinition()==typeof(Cat))
{
a、 GetMethod(“MethodUniqueToCats”).Invoke(null,null)
}
我个人不会这么做,除非你必须这么做。
我会在这里避免反射,也就是说,我会添加接口
ICat
和IDog
,并尝试在您的方法中对其进行转换。如果您绝对希望这样做(并且违反了),那么最简单的方法就是为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();
}
如果您需要这样做,您违反了您不能这样做的规则,除非该接口传递的对象确实是您要将其强制转换为的类型。您不能将其强制转换为与其实际类型(及其基类型)不同的类型。您的问题中没有泛型代码。是的,您使用的是泛型,但它们不是泛型代码。另外,如果您需要转换为具体类型,请不要发送接口,因为这样您的代码就不会绑定到接口,而是绑定到实际类型。@Psi:我想按照编码,然后强制转换。@Codingyosi:这只是代码的骨架,是一个模拟。你可以假设泛型被使用,但不是在那些点上。你可以分享为什么你不这样做,为什么需要避免反射?@PieruPoika你可以读这个主题:@PieruPoika那么你必须实现一个策略模式我明白了在阅读了更多的文章之后,iskov替换原则(LSP)现在有了更多的内容。我认为不应该违反它。因此,我将此解释标记为一个答案,并强调:如果可能,请避免使用它,因为它违反了LSP:)这是正确的答案,但从ICat接口而不是Cat类实现IAnimal是有意义的。
IAnimal animal = new Cat<int>();
var cat = animal as ICat;
if (cat != null)
{
cat.MethodUniqueToCats();
}
if (animal is ICat cat)
{
cat.MethodUniqueToCats();
}