2014-10-13 4 views
3

У меня есть следующие:InstanceOf проверить динамического типа

interface IViewable {} 

class Node {} 

class DecisionNode : Node, IViewable {} 

В одном сегменте приложения, у меня есть следующий метод, к которому я передать экземпляр DecisionNode:

void handleNode (Node node) 
{ 
    // ... 
    var viewable = node as IViewable; 
    // ... 
} 

проблема в том, что это, похоже, не проверяет, действительно ли динамический/runtime-тип node является подклассом IViewable. Он правильно исключает, что это относится к статическому типу (Node), но это не то, что я хочу проверить. Я получаю тот же результат, если попытаюсь использовать или использовать is.

Для решения этой проблемы рекомендуется использовать GetType().IsAssignableFrom(), но платформа, которую я использую (Xamarin), не позволяет этого.

Есть ли другой способ проверить, может ли динамический тип моего объекта обрабатываться как экземпляр заданного типа?

ответ

4

as сделать проверку типа; он просто возвращает null, если проверка не удалась, который вы можете проверить с if:

if(viewable != null) { 
     ... 
} else { 
     ... 
} 

Re:

node не может рассматриваться как пример IViewable

Это правильно; однако viewableможет быть; просто запустите IViewable-связанный код с viewable.

Если вы хотите утвердить, что это преобразование должно всегда работать; просто отлитые:

var viewable = (IViewable)node; 

В качестве примера, следующие мероприятия:

DecisionNode: True 
Node: False 

код:

class Program 
{ 
    static void Main() 
    { 
     var prog = new Program(); 
     prog.handleNode(new DecisionNode()); 
     prog.handleNode(new Node()); 
    } 
    void handleNode(Node node) 
    { 
     var viewable = node as IViewable; 
     System.Console.WriteLine("{0}: {1}", 
      node.GetType().Name, 
      viewable != null); 
    } 
} 
interface IViewable { } 
class Node { } 
class DecisionNode : Node, IViewable { } 

Если вы не можете заставить его работать, рассмотреть:

// play hunt the interface 
if(viewable == null) { 
    foreach(Type iType in node.GetType().GetInterfaces()) { 
     if(iType.Name == "IViewable") { 
      Console.WriteLine("{0} vs {1}", 
       iType.AssemblyQualifiedName, 
       typeof(IViewable).AssemblyQualifiedName); 
     } 
    } 
} 
+0

Я понимаю, что, но проблема в том, не является ли 'as' для typecheck, а скорее * how *, я могу typecheck на основе динамического типа объекта, поскольку, кажется,' as' делает это только на основе статический тип. Я знаю, что этот узел в этом случае является экземпляром 'DecisionNode', а следовательно, и экземпляром' IViewable', но typecheck не выдерживает этого. – csvan

+3

@chrsva no, 'is' и' as' работают против типа среды выполнения, а не статического типа. Я намеренно не использую термин «динамический тип», потому что это путает с 'dynamic' и т. Д., Что не связано. Если ваш тип-проверка работает некорректно, то я подозреваю, что фактическая проблема - это что-то еще - возможно, декларация о дубликат интерфейса. –

+0

@chrsva см. Edit для примера кода –

3

as. Сделать тип проверка.

as ключевое слово делает какой-то «мягкой» литья, он пытается, и если это не удается, он возвращается к null:

СОС оператор подобен операции приведения. Однако, если преобразование невозможно, так как возвращает null вместо создания исключения.

Так проверьте null и вы будете знать, если viewable является null или нет запрашиваемый тип:

var viewable = node as IViewable; 
if (viewable != null) 
{ 
    // go ahead! 
} 

Или проверить с помощью is:

if (node is IViewable) 
{ 
    var viewable = (IViewable)node; // this is safe now 
    // go ahead! 
} 
+0

Обратите внимание, что первый подход (нулевая проверка) рекомендуется для производительности. И в C# 6 мы можем написать 'if ((var viewable = node as IViewable)! = Null) {...}' – Bas

+1

@ Интересно, что нет простого выбора между 'is' + cast versus' as' + нуль-проверки; существует множество сценариев, где каждый быстрее. В большинстве повседневных применений * это не имеет значения * –

Смежные вопросы