Как проверить, являются ли параметры нулевыми при использовании конструкторов позиционных записей и/или свойств инициализации?

#c# #.net

Вопрос:

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

Итак, вопрос: Можно ли проверить во время выполнения, что полям записи не будут присвоены значения null? Если да, то как это можно сделать, все еще используя записи?

 public record Test(string TestString)
{
   /// <summary>
   /// This is one way to get a comment on record properties. Are there others?
   /// </summary>
   public string TestString { get; init; } = TestString;
}
 

Код также является основной идеей здесь.

Это дополнение, но, возможно, поможет с принятым ответом и комментарием другого кода.

Это было потому, что код в gist выполнял проверку на нуль, например

 public record Test(string TestString)
{
   /// <summary>
   /// This is one way to get a comment on record properties. Are there others?
   /// </summary>
   public string TestString { get; init; } = TestString ?? throw new ArgumentNullException();
}
 

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

<редактировать: .NET 6 ArgumentNullException.ThrowIfNull(obj) может быть полезен здесь (или ThrowHelper).

Комментарии:

1. Код в вашей сути отличается.

2. Я мог бы ошибаться здесь, но я подумал, что если вы включите nullable в своем проекте и будете соблюдать предупреждения компилятора, то ввода null там не произойдет, и было бы безопасно предположить, что testString НЕ является нулевым, потому что вы доверяете значению. Если вы хотите принять значение null, которое вы хотели бы иметь string? вместо просто string .

3. @TravisWhidden, я думаю, я сформулировал неточно, но мне интересно, какой из них был бы самым чистым способом сделать это. Не прибегая к чтению спецификации о том, как это определено.

Ответ №1:

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

Одна из возможностей-вызвать метод расширения, чтобы обернуть любое поведение.

 public record Test(string TestString)
{
    /// <summary>
    /// This is one way to get a comment on record properties. Are there others?
    /// </summary>
    public string TestString { get; init; } = ValidationExtensions.Validate(TestString);
}

public static class ValidationExtensions
{
    public static string Validate(string input)
    {
        if (string.IsNullOrEmpty(input))
            throw new NullReferenceException();
        
        return input;
    }
}
 

Это приведет к правильному броску во время инициализации записи:

 var x = new Test(null);
 

Комментарии:

1. Хех, другой комментатор оставил заметку , что код был другим, так как у него был фрагмент с ?? нулевым объединением, потому что я вращался вокруг этой идеи, но думал, можно ли так добавлять комментарии и проверять. Может быть, a ThrowHelper или частные статические шашки тоже кому-то подходят, я добавлю здесь для последующих читателей. 🙂 Спасибо, что потрудились привести этот наглядный пример!