【问题标题】:C#.NET - How can I get typeof() to work with inheritance?C#.NET - 如何让 typeof() 与继承一起工作?
【发布时间】:2010-11-16 03:11:56
【问题描述】:

我将首先在代码中解释我的场景:

public class A { }

public class B : A { }

public class C : B { }

public class D { }

public class Test
{
    private A a = new A ( ) ;
    private B b = new B ( ) ;
    private C c = new C ( ) ;
    private D d = new D ( ) ;

    public Test ( )
    {
        // Evaluates to "false"
        if ( a.GetType == typeof(B) ) { } //TODO: Add Logic

        // Evaluates to "true"
        if ( b.GetType == typeof(B) ) { } //TODO: Add Logic

        // I WANT this to evaluate to "true"
        if ( c.GetType == typeof(B) ) { } //TODO: Add Logic

        // Evaluates to "false"
        if ( d.GetType == typeof(B) ) { } //TODO: Add Logic
    }
}

这里需要注意的重要一点是:

if ( c.GetType == typeof(B) ) { }

我相信这实际上会评估为“假”,因为 typeof(B) 和 typeof(C) 在两个方向上都不相等。 (C 是 B,但 B 不一定是 C。)

但我需要的是某种考虑到这一点的条件。如何判断一个对象是 B 还是从它派生的任何东西?

我不在乎它是否是从 B 派生的对象,只要基 B 类在那里。而且我无法预料我的应​​用程序中可能会出现什么派生类。我只需要假设将来可能存在未知的派生类——因此我只能专注于确保基类是我所期望的。

我需要一个条件来为我执行此检查。这如何实现?

【问题讨论】:

  • 你应该尽可能避免这种逻辑。当您必须确定对象的派生类型是什么时,您并没有很好地利用多态性。
  • 查看我对 Steven Sudit 回答的评论。

标签: c# .net inheritance typeof


【解决方案1】:

编辑:这回答了线程标题中的问题。如全文所述,cdm9002 对问题有更好的答案。

typeof(B).IsAssignableFrom(c.GetType())

【讨论】:

  • cdm9002 的答案更好,因为它不使用反射。
  • @pb:如果你想获得技术,另一个答案不使用typeof 继承。正如您从我的编辑中看到的那样,我不会声称我想到的第一个答案是最合适的。 :)
  • 这不仅是一个完全正确的答案,而且还涵盖了当您手头没有任何类的实例,但仍想确定是否存在继承关系的情况两种类型之间。
【解决方案2】:

你可以使用is:

if (c is B) // Will be true

if (d is B) // Will be false

【讨论】:

  • 作为对 OP 中唯一实际问题的回答:“我如何判断一个对象是 B 还是从它派生的任何东西?”这是正确的答案。我的是线程标题的答案,但不太适合所描述的问题。
  • 啊,确实如此。你是对的,我的问题在那里有点糊涂。我的错。
【解决方案3】:

这看起来像是多态性的工作,而不是用于测试特定类的大型 switch 语句。

【讨论】:

  • 确实如此。在类A上放一个虚方法,在子类中酌情覆盖,然后调用这个虚方法。
  • 多么粗鲁!哈哈。我的课堂逻辑实际上并不像这样一团糟。我只需要弄清楚如何执行此条件。我正在抽象基类中编写 PropertyChangedCallback 方法,我需要一个安全条件来确保 DependencyObject 参数是从我的基类派生的对象。如果不是,我会抛出错误或取消我的逻辑。在这种情况下,多态性没有帮助。
  • 好的,那么使用“is”就足够了。
【解决方案4】:

对于带有 Visual Studio 2008 的 VB.NET,您可以像这样检查它:

'MyTextBox control is inherited by Textbox
If Ctl.GetType.Name = "MyTextBox" then    

End If

【讨论】:

    【解决方案5】:

    作为(c is B) 检查的替代方法,您还可以执行以下操作:

    var maybeB = c as B;
    if (maybeB != null) {
       // make use of maybeB
    }
    

    在某些情况下这是首选,因为为了在使用 is 时将 c 用作 B,无论如何您都必须强制转换。

    【讨论】:

      【解决方案6】:
      typeof(B).IsInstanceOfType(c)
      

      与上面来自 sam-harwell 的答案类似,有时您可能在变量中有类型“B”,因此您需要使用反射而不是“is”运算符。

      我使用了 Sam 的解决方案,当 Resharper 提出这个建议时,我感到很惊喜。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-27
        相关资源
        最近更新 更多