С# делегаты variance не работают с int

Объясните мне логику, почему я получаю ошибку компиляции в случае 3?

Все эти типы являются производными от Object. В чем тогда проблема?

public delegate object DelegateType();
public static void Main()
{
    DelegateType case1 = Test;
    DelegateType case2 = Test2;
    DelegateType case3 = Test3;
}

public static string Test()
{
    return 1.ToString();
}
public static ValueType Test2()
{
    return 1;
}
public static int Test3()
{
    return 1;
}

Проверьте этот - не прямой ответ, но также может дать некоторое представление.

Guru Stron 04.04.2023 12:59

@GuruStron, с моей точки зрения, почти то же самое, что Марк также упомянул в своем ответе. Кроме того, кажется, ваша ссылка полностью попадает в точку. С моей точки зрения явный дурак.

MakePeaceGreatAgain 04.04.2023 13:21

@MakePeaceGreatAgain - это очень похоже, но касается конкретно общих аргументов. Первоначально я закрыл вопрос как дублирующий, но потом решил, что они достаточно различаются.

Guru Stron 04.04.2023 13:22

Неупакованные типы значений не наследуются от System.Object

Charlieface 04.04.2023 15:36

@Charlieface Они делают это. не напрямую, а через класс ValueType

ps1Xt 05.04.2023 10:13

Нет, не делают, если только не в коробке. Если они упакованы, то да, но неупакованный тип значения — это просто голое значение, у него нет базового класса. См. эту ссылку, есть и другие места, где это отмечено, например, спецификация ECMA-335 Раздел 8.2.4 ecma-international.org/wp-content/uploads/…

Charlieface 05.04.2023 12:06

В этом разделе нет информации о том, что неупакованное значение не наследуется от ValueType или Object. Вот только информация о том, что если вам нужно коробочное значение, то его нужно привести к типу ValueType или Object. В документации написано Object -> ValueType -> Int32 ссылка

ps1Xt 05.04.2023 12:34

Конец этого раздела «Интерфейсы и наследование определяются только для ссылочных типов. Таким образом, хотя определение типа значения (§8.9.7) может указывать как интерфейсы, которые должны быть реализованы типом значения, так и классом (System.ValueType или System. Enum), от которых он наследуется, они применяются только к значениям в коробках».

Charlieface 05.04.2023 14:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вариантность один раз работает для ссылочных типов, т.е. там, где есть сохраняющее значение (без каких-либо операций) преобразование между типами. Упаковка/распаковка: не считается сохранением значения, поэтому: нет различий между типами значений и объектами или типами значений и интерфейсами, которые реализуют эти типы значений.

Это основано на недоразумении.

Неупакованные типы значений не наследуются ни от чего, даже System.ValueType.

Спецификация .NET разъясняет это, ECMA-335, раздел 8.2.4:

Интерфейсы и наследование определяются только для ссылочных типов. Таким образом, в то время как определение типа значения (§8.9.7) может указывать как интерфейсы, которые должны быть реализованы типом значения, так и класс (System.ValueType или System.Enum), от которого он наследуется, они применяются только к упакованным значениям.

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

Другие вопросы по теме