С#.NET. Как я могу заставить typeof() работать с наследованием?

Начну с объяснения моего сценария в коде:

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. И я не могу предвидеть, какой производный класс может появиться в моем приложении. Я просто должен предположить, что неявные производные классы могут существовать в будущем - и поэтому я могу сосредоточиться только на том, чтобы базовый класс был тем, чего я ожидаю.

Мне нужно условие, которое будет выполнять эту проверку для меня. Как это можно сделать?

Ответ 1

Вы можете просто использовать is:

if (c is B) // Will be true

if (d is B) // Will be false

Ответ 2

Изменить: это отвечает на вопрос в заголовке темы. cdm9002 имеет лучший ответ на проблему, как описано в полном сообщении.

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

Ответ 3

Это выглядит как задание для полиморфизма, в отличие от большого оператора switch с тестами для определенных классов.

Ответ 4

В качестве альтернативы проверке (c is B) вы также можете сделать следующее:

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

Это предпочтительнее в некоторых случаях, так как для использования c в качестве B при использовании is вам все равно придется бросать.

Ответ 5

Для VB.NET с Visual Studio 2008 вы можете проверить это как:

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

End If

Ответ 6

typeof(B).IsInstanceOfType(c)

Как и в ответе выше от sam-harwell, иногда у вас может быть тип "B" в переменной, поэтому вам нужно использовать отражение, а не оператор "is".

Я использовал решение Сэма и был приятно удивлен, когда Решарпер сделал это предложение.