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


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

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

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

if(controllerType is IController) { ... }

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

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

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

4 ответа:

это не то же самое.

if(controllerType is IController)

б всегда оценка для false С controllerType всегда a Type и Type никогда IController.

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

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

typeof(IController).IsAssignableFrom(controllerType) тесты Type в отношении интерфейса. Элемент is оператор проверяет экземпляр по интерфейсу.

is ключевое слово применяется только для случаев, в то время как тип.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, это объект типа, представляющий тип String.

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

    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 " (и параметр универсального типа) требует знания конкретных типов во время компиляции.