C# Классы больше не обнуляемые?

Используя С# в .NET 6.0, я сталкиваюсь с предупреждениями, в которых говорится: «Невозможно преобразовать нулевой литерал в ненулевой ссылочный тип». Я думал, что классы могут быть нулевыми и могут быть установлены как нулевые...

Это выдает предупреждение:

    public class Foo
    {
        public string Name { get; set; }

        public Foo()
        {
            Name = "";
        }
    }

    public class Bar
    {
        public Foo fooClass;

        public Bar()
        {
            // Because I don't want to set it as anything yet.
            fooClass = null;
        }

        public void FooBarInit()
        {
            fooClass = new Foo();
        }
    }

Но это не дает мне предупреждения

    public class Foo
    {
        public string Name { get; set; }

        public Foo()
        {
            Name = "";
        }
    }

    public class Bar
    {
        public Foo? fooClass;

        public Bar()
        {
            // Because I don't want to set it as anything yet.
            fooClass = null;
        }

        public void FooBarInit()
        {
            fooClass = new Foo();
        }
    }

Однако теперь давайте попробуем использовать переменную Name в Foo внутри Bar.

    public class Foo
    {
        public string Name { get; set; }

        public Foo()
        {
            Name = "";
        }
    }

    public class Bar
    {
        public Foo? fooClass;

        public Bar()
        {
            // Because I don't want to set it as anything yet.
            fooClass = null;
        }

        public void FooBarInit()
        {
            fooClass = new Foo();
        }

        public void FooBarTest()
        {
            Console.WriteLine(fooClass.Name); // Warning here which tells me fooClass maybe null
        }
    }

Однако FooBarTest никогда не запустится без предварительного запуска FooBarInit. Так что он никогда не будет нулевым, и если это так, у меня будет ситуация с обработкой ошибок после этого.

Мой вопрос: почему я должен устанавливать классы так, чтобы они разрешали null, когда они все равно должны принимать null?

Если я использую "?" после объявления класса... Теперь мне нужно проверить, является ли он нулевым... В ЛЮБОЙ раз, когда я хочу вызвать этот класс, мой код выглядит ужасно. Есть исправления или возможность отключить?

learn.microsoft.com/en-us/dotnet/csharp/nullable-references

gunr2171 13.10.2022 23:52

См. здесь: learn.microsoft.com/en-us/dotnet/csharp/nullable-references . Начиная с .NET 6, для новых проектов ссылочные типы/контекст, допускающие значение NULL, включены по умолчанию.

user19858830 13.10.2022 23:52
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
98
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Хотя это очень хорошая функция, вы все равно можете отключить ее, изменив значение свойства Nullable на disable в вашем файле .csproj:

  <PropertyGroup>
    ...
    <Nullable>disable</Nullable>
    ...
  </PropertyGroup>

Я признаю, что это отличная функция для предотвращения сбоев, но решение о ней должно быть оставлено на усмотрение программиста... Однако интересно, почему нет возможности отключить ее в реальных свойствах Visual Studio. Еще раз спасибо кстати

ShadowEvil 13.10.2022 23:59

@ShadowEvil В VS2022 в свойствах проектов в Build -> General есть параметр Nullable.

Jonathan Dodds 14.10.2022 00:01

@JonathanDodds Спасибо! Я предпочитаю не возиться в сгенерированном файле! LOL

ShadowEvil 14.10.2022 00:03

На самом деле для этого есть настройка проекта в пользовательском интерфейсе. Он находится в разделе «Сборка»> «Общие».

Vivelin 14.10.2022 08:38

Файлы .*proj в Visual Studio @ShadowEvil представляют собой MSBuild и предназначены как для редактирования вручную, так и для обновления в среде IDE. Возиться с файлом проекта безопасно.

Jonathan Dodds 14.10.2022 18:51

Если вы знаете, что значение типа, допускающего значение NULL, не может быть нулевым, вы можете использовать оператор , допускающий нуль, .

Console.WriteLine(fooClass!.Name);

Вы также можете (что странно для этого разработчика Kotlin) присвоить null ненулевому типу, используя этот механизм:

public Foo fooClass = null!;

Этот ответ предполагает, что он похож на использование lateinit в Kotlin, который говорит компилятору: «Я обещаю, что к тому времени, когда я начну его использовать, для этого будет установлено что-то ненулевое». Вы можете инициализировать переменную нулевым значением с помощью этой техники, но вы не можете установить ее в нуль позже.

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