Типы ссылок по умолчанию допускают значение NULL, и можно присвоить строке значение NULL. В чем смысл строки? затем? Какая разница в данном случае?
string? означает, что переменная может содержать допустимую строку или null, тогда как string должно содержать только допустимое строковое значение.
Взято непосредственно из MSDN: «Цель этой функции состоит в том, чтобы: позволить разработчикам выразить, будет ли переменная, параметр или результат ссылочного типа иметь нулевое значение или нет. Предоставлять предупреждения, когда такие переменные, параметры и результаты используются не в соответствии с с этим намерением».





Об этом было написано много статей, но TLDR заключается в том, что типы, допускающие значение NULL, не были созданы до C# 2.0, и поэтому все это результат истории, как все интерпретируется сейчас. Для строки обратной совместимости без ? должно быть обнуляемым.
Вы имеете в виду ссылочные типы, допускающие значение NULL? представлено в C# 8/.Net core 3? AFAIK null существует с C# 1.
Насколько я помню, типы значений, допускающие значение NULL (например, int?), были представлены примерно в 2005 году (C# 2.0). Строка особенная, но был ли введен синтаксис вопросительного знака вместе с языком, а затем строка и строка? последовал бы за int и int? логика.
Но строка не является типом значения. Конечно, ссылочные типы, допускающие значение NULL, повторно использовали синтаксис ?, но string? недействителен до версии C# 8.
строка является специальной и представляет собой один из двух ссылочных типов, специально указанных в спецификации Ecma. (другой является объектом). Когда был выпущен C# 2.0, по этому поводу было много споров, но сделать это было невозможно. Итак, то, что мы имеем сегодня, — это сочетание истории.
Если вы используете C# 8.0 или более позднюю версию с включенными ссылочными типами, допускающими значение NULL, ожидается, что переменная string никогда не будет null, и компилятор выдаст предупреждения, если ей может быть присвоено значение null.
string nonNullableString = null; //Compiler warning with nullable reference types enabled
string? nullableString = null; //No compiler warning
Функциональность та же, но, например, когда вы присваиваете значение null элементу string, вы можете получить предупреждение CS8600, а при использовании string? — нет, потому что вы явно объявили поле, допускающее значение NULL.
string? и string относятся к одному типу. Это справедливо для всех ссылочных типов и только для ссылочных типов.
В контексте, допускающем значение NULL, ? — это подсказка, сообщающая, что null является допустимым значением для этого поля, переменной, параметра или возвращаемого значения. С другой стороны, отсутствие ? означает, что значение null не ожидается. Это позволяет компилятору выполнять статический анализ вашего кода и выдавать предупреждение, если это может привести к исключению нулевой ссылки. Это также позволяет избежать ненужных проверок на ноль.
Итак, вы знаете о «обнуляемом». Вы знаете о «ссылочных типах». Что вы обнаружите, если будете искать эти три слова вместе? Здесь уже написано много статей и задано много вопросов.