C # .NET - Как я могу заставить typeof () работать с наследованием? - PullRequest
15 голосов
/ 02 августа 2009

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

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

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

Ответы [ 6 ]

40 голосов
/ 02 августа 2009

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

if (c is B) // Will be true

if (d is B) // Will be false
23 голосов
/ 02 августа 2009

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

typeof(B).IsAssignableFrom(c.GetType())
4 голосов
/ 02 августа 2009

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

1 голос
/ 27 сентября 2015

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

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

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

0 голосов
/ 28 октября 2015
typeof(B).IsInstanceOfType(c)

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

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

0 голосов
/ 03 сентября 2013

Для VB.NET с Visual Studio 2008 вы можете проверить его следующим образом:

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

End If
...