Arhn - архитектура программирования

Контравариантные типы значений делегатов

Может ли кто-нибудь пролить свет на то, почему контравариантность не работает с типами значений С#?

Ниже не работает

private delegate Asset AssetDelegate(int m);

internal string DoMe()
{
    AssetDelegate aw = new AssetDelegate(DelegateMethod);
    aw(32);
    return "Class1";
}

private static House DelegateMethod(object m)
{
    return null;
}
09.06.2010

  • Я бы опубликовал ответ, но я не хочу возиться с формулировкой. Проверьте запись в блоге Эрика Липперта здесь, особенно комментарии. blogs.msdn.com/b/ericlippert/archive/2007/10/19/ Это похоже на случай, когда значения ссылочного типа имеют одинаковый объем памяти, что не является case для типов значений. С учетом сказанного DelgateMethod можно было бы сделать универсальным, который затем поддерживал бы целые, длинные и т. д. 09.06.2010

Ответы:


1

Проблема в том, что int не является объектом.

Int может быть упакован в объект. Результирующий объект (также известный как упакованный int), конечно же, является объектом, но уже не совсем int.

Обратите внимание, что «is», который я использую выше, не совпадает с оператором C# является. Мое «является» означает «преобразуется с помощью неявного преобразования ссылки». Это значение «is» используется, когда мы говорим о ковариантности и контравариантности.

Int неявно преобразуется в объект, но это не преобразование ссылки. Его надо запаковать.

House можно неявно преобразовать в Asset посредством преобразования ссылки. Нет необходимости создавать или изменять какие-либо объекты.

Рассмотрим пример ниже. Обе переменные house и asset ссылаются на один и тот же объект. Переменные integer и boxedInt, с другой стороны, содержат одно и то же значение, но ссылаются на разные объекты.

House house = new House();
Asset asset = house;

int integer = 42;
object boxedInt = integer;

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

11.06.2010
  • На мой взгляд, попытка сделать вид, что типы значений происходят от System.Object, бесполезна. Гораздо полезнее признать, что для каждого типа значения существует связанный тип упакованного класса, производный от System.ValueType. Типы значений неявно преобразуются в их эквиваленты типа класса, а явное приведение может использоваться для копирования содержимого упакованного типа значения обратно в реальный. 27.06.2012

  • 2

    Я согласен с комментарием Энтони Пеграма - он основан на том, что ссылочные типы имеют другой объем памяти, чем типы значений: CLR может неявно использовать класс одного типа в качестве класса своего супертипа, но когда вы начинаете использовать типы значений, CLR потребуется упаковать ваше целое число, чтобы оно могло работать вместо объекта.

    Если вы все равно хотите, чтобы это работало, у меня есть тенденция заключать объявление в выражение:

    AssetDelegate aw = new AssetDelegate((m) => DelegateMethod(m));
    

    Я не знаю, является ли это хорошей практикой с точки зрения синтаксиса, но помните, что упаковка и распаковка стоят дорого.

    09.06.2010
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..