在运行时获取对象类型

4

我有以下代码。我得到了一个我不知道类型的对象。我必须检查三个条件来检查它的类型,然后进行正确的转换。

有没有办法在运行时获取对象类型并进行转换,而不需要检查任何if条件?

我拥有的对象是requirementTemplate,我必须检查许多类型以获取其类型,然后进行转换。

if (requirementTemplate.GetType() == typeof(SRS_Requirement))
{
    ((SRS_Requirement)((TreeNodeInfo)ParentTreeNode.Tag).Handle).AssociatedFeature = ((SRS_Requirement)requirementTemplate).AssociatedFeature;
}
else if (requirementTemplate.GetType() == typeof(CRF_Requirement))
{
    ((CRF_Requirement)((TreeNodeInfo)ParentTreeNode.Tag).Handle).AssociatedFeature = customAttr.saveAttributesCustomList(AttributesCustomListCloned);
}
else if (requirementTemplate.GetType() == typeof(SAT_TestCase))
{
    ((SAT_TestCase)((TreeNodeInfo)ParentTreeNode.Tag).Handle).AssociatedFeature = ((SAT_TestCase)requirementTemplate).AssociatedFeature;
}

1
为什么这个标签有三个不同的C#版本?它是哪一个? - Aaronaught
如果你首先将 ((TreeNodeInfo)ParentTreeNode.Tag).Handle 提取到一个单独的变量中,你的代码会更加清晰易懂。你还应该考虑使用 is 而不是调用 GetType() - Jon Skeet
2个回答

3

1
这在技术上是正确的答案,尽管它没有解决由代码墙所暗示的令人震惊的糟糕设计问题。 - Aaronaught
我不认为这会对他的设计有所帮助。他仍然需要硬编码类型以进行转换,以便访问AssociatedFeature属性。因此,他仍然需要所有的if语句,而这正是他想要减少的...其他答案(接口)更加合适。 - musefan
我会说这就是回答“有没有办法在运行时获取对象类型并进行转换,而不需要检查任何if条件?”的答案:D - Incognito

2

在这里最合适的答案是实现一个通用接口,或者覆盖一个来自通用基类的虚拟方法,并使用多态性在运行时提供(从各种实现类中)的实现。然后你的方法变成了:

(blah.Handle).AssociatedFeature  = requirementTemplate.GetAssociatedFeature();

如果列表不是排他的(即存在其他实现),则:

var feature = requirementTemplate as IHasAssociatedFeature;
if(feature != null) {
    (blah.Handle).AssociatedFeature = feature.GetAssociatedFeature();
}

你也可以在左侧执行类似的操作,或将其作为上下文传递:

var feature = requirementTemplate as IHasAssociatedFeature;
if(feature != null) {
     feature.SetAssociatedFeature(blah);
}

另一种常见的方法是在此处使用枚举进行switch


(if necessary)
switch(requirementTemplate.FeatureType) {
     case ...
}

这个技术的一个好处是它可以既针对特定类型,也可以针对特定实例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接