Использование `NullReferenceException`

Да, я знаю что NullReferenceException — это системная ошибка (наследование от SystemException + применение), но что мне выбрасывать вот в таком коде:

public interface IMyInterface
{
    void Import(IModuleSource module);
}
public static class MyExtensions
{
    public static void ImportKernel(this IMyInterface @this)
    {
        @this.Import(new KernelSource(KernelVersion.Latest)); // импортируем ядро
    }
}

ПРИМЕЧАНИЕ. Псевдо-код. Фокус должен быть не на методах Import и ImportKernel, а на "прологе" метода ImportKernel.

Тут есть 1 проблема — параметр @this в методе ImportKernel может быть null. Следовательно, этот вход нужно обработать. И тут возникает 2 способа решения:

if (@this is null) throw new ArgumentNullException(nameof(@this));
if (@this is null) throw new NullReferenceException();

Кажется, что 2-й способ неконкурентоспособен, но метод ImportKernel можно вызвать также по разному:

IMyInterface obj = null!;

// исключение `ArgumentNullException` не уместно, т.к. мы не передаём аргумент `this`
// исключение `NullReferenceException` выглядит естественно
obj.ImportKernel();
// исключение `ArgumentNullException` выглядит естественно
// исключение `NullReferenceException` выглядит не уместно, т.к. класс `MyExtensions` не может быть `null` (да он, собственно, и не объект)
MyExtensions.ImportKernel(null!);

И не понятно, что делать?

Конечно, можно создать своё исключение — ObjectNullException, но оно не входит в стандартную библиотеку, значит у каждого будет по такому исключению, что не хорошо.

Собственно, вопрос: какое исключение лучше выбрасывать в данной ситуации (или не выбрасывать ничего на крайняк)?


Ответы (2 шт):

Автор решения: Aziz Umarov

Вариант собственно очевидный для меня. Для кого другой пишите свой ответ.

Вариант. if (@this is null) throw new NullReferenceException(); Не имеет смысла поскольку следующая команда сделает это за вас.

Писать своё исключение это хорошая практика. (не утверждаю о правильности, правильно и хорошо не инвариант. Всё индивидуально).

→ Ссылка
Автор решения: Bulson

Я бы сделал лучше так

public static class MyExtensions
{
    public static bool IsImportKernelSuccess(this IMyInterface @this)
    {
        if (@this is null)
            return false;

         @this.Import(new KernelSource(KernelVersion.Latest));
         return true;
    }
}

Или можно еще попытаться избежать на входе в метод null с помощью паттерна NullObject.

→ Ссылка