Использование IsAssignableFrom и ключевое слово «is» в C #

При попытке изучить Unity я продолжаю видеть следующий код для переопределения GetControllerInstance в MVC:

 if(!typeof(IController).IsAssignableFrom(controllerType)) { ... } 

это кажется мне довольно запутанным способом в основном писать

 if(controllerType is IController) { ... } 

Я понимаю, что есть тонкие различия между is и IsAssignableFrom , то есть IsAssignableFrom не включает преобразования конверсий, но я изо всех сил пытаюсь понять последствия этой разницы в практических сценариях.

Когда это целесообразно, чтобы выбрать IsAssignableFrom over? Какая разница в GetControllerExample ?

 if (!typeof(IController).IsAssignableFrom(controllerType)) throw new ArgumentException(...); return _container.Resolve(controllerType) as IController; 

Это не одно и то же.

 if(controllerType is IController) 

всегда будет оцениваться как false так как controllerType всегда является Type , а Type никогда не является IController .

Оператор is используется для проверки совместимости экземпляра с данным типом.

Метод IsAssignableFrom используется для проверки совместимости типа с данным типом.

typeof(IController).IsAssignableFrom(controllerType) проверяет Type на интерфейс. Оператор-оператор проверяет экземпляр интерфейса.

ключевое слово применимо только для экземпляров, тогда как Type.IsAssignableFrom () применимо только для типов.

примером is

 string str = "hello world"; if(str is String) { //str instance is of type String } 

Обратите внимание, что str – это экземпляр, а не тип.

пример IsAssignableFrom()

 string str = "hello world"; if(typeof(Object).IsAssignableFrom(str.GetType())) { //instances of type String can be assigned to instances of type Object. } if(typeof(Object).IsAssignableFrom(typeof(string))) { //instances of type String can be assigned to instances of type Object. } 

Обратите внимание, что аргумент для IsAssignableFrom () не является экземпляром String, это объект Type, представляющий тип String.

Заметная разница также в том, что «is» делает интуитивный смысл для тестирования наследования или реализации интерфейса, тогда как IsAssignableFrom делает что-то, кроме ощущения на первый взгляд. Имя метода Type.IsAssignableFrom является неопределенным и запутанным при применении к тестированию наследования или обнаружению реализации интерфейса. Следующая shell для этих целей сделала бы более понятный и удобочитаемый код приложения:

  public static bool CanBeTreatedAsType(this Type CurrentType, Type TypeToCompareWith) { // Always return false if either Type is null if (CurrentType == null || TypeToCompareWith == null) return false; // Return the result of the assignability test return TypeToCompareWith.IsAssignableFrom(CurrentType); } 

Затем можно иметь более понятный синтаксис клиента, например:

  bool CanBeTreatedAs = typeof(SimpleChildClass).CanBeTreatedAsType(typeof(SimpleClass)); CanBeTreatedAs = typeof(SimpleClass).CanBeTreatedAsType(typeof(IDisposable)); 

Преимущество этого метода вместо ключевого слова is is заключается в том, что его можно использовать во время выполнения для проверки неизвестных произвольных типов, тогда как ключевое слово «is» (и общий параметр типа) требует знания времени определенных типов определенных типов ,

  • Работа с ArrayStoreException
  • Как заставить Java-метод возвращать общий список любого типа?
  • Неявные правила преобразования типов в операторы C ++
  • Быстрая двойная строка
  • Является ли поведение приведения отрицательного двойного к unsigned int, определенного в стандарте C?
  • printf указывает строку целочисленного формата для float
  • Безопасно ли удалять указатель на пустоту?
  • Почему переменная NSInteger должна быть отброшена дольше при использовании в качестве аргумента формата?
  • Как вы перечислите список супертипов в список подтипов?
  • Давайте будем гением компьютера.