Подтвердить что ты не робот

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

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

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

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

if(controllerType is IController) { ... }

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

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

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

Ответ 1

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

if(controllerType is IController)

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

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

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

Ответ 2

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

Ответ 3

is ключевое слово применимо только для экземпляров, тогда как 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.

Ответ 4

Заметная разница также в том, что "is" делает интуитивный смысл для тестирования наследования или реализации интерфейса, тогда как IsAssignableFrom делает что-то, кроме ощущения на первый взгляд. Имя метода Type.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 заключается в том, что его можно использовать во время выполнения для проверки неизвестных произвольных типов, тогда как ключевое слово "is" (и общий параметр типа) требует знания времени компиляции определенных типов.