CA2208 при создании ArgumentOutOfRangeException при использовании поля класса в качестве аргумента - PullRequest
0 голосов
/ 06 февраля 2020

Я генерирую ArgumentOutOfRangeException при проверке правильных значений перечисления:

internal class MyClass : IMyInterface
{
    private readonly MyEnum _myEnum;

    public MyClass(MyEnum myEnum) => _myEnum = myEnum;

    public String MyString
    {
        get
        {
            switch (_myEnum)
            {
                case MyEnum.A:
                    return "A";
                case MyEnum.B:
                    return "B";
                default:
                    throw new ArgumentOutOfRangeException("_myEnum");
            }
        }
    }
}

Я получаю ошибку CA2208 при сборке:

Метод CA2208 'MyCLass.MyString. get () передает _myEnum в качестве аргумента paramName в конструктор ArgumentOutOfRangeException. Замените этот аргумент одним из имен параметров метода. Обратите внимание, что указанное имя параметра должно иметь точный регистр, объявленный в методе.

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

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

Примечание. Свойство MyString является частью объекта IMyInterface и не может принимать это значение перечисления в качестве аргумента.

1 Ответ

1 голос
/ 06 февраля 2020

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

Это потому, что все, что вы там передадите, будет опубликовано в ParamName свойство исключения, которое определяется как

Получает имя параметра, вызывающего это исключение.

Теперь, если что бы там ни было , а не имя параметра, все может запутаться для любого, кто обрабатывает исключение. В некоторых случаях ArgumentException и ParamName могут даже оцениваться с помощью отражения, которое может завершиться ошибкой, если имя параметра не найдено.

Если вы действительно хотите предоставить пользовательское сообщение для ArgumentException, вы можете использовать конструктор , который принимает пользовательское сообщение и исключение (и передает null для исключения).

Однако , как ваш исключение не указывает на недопустимый аргумент , я бы сказал, что ArgumentException не является правильным исключением для использования. Вы генерируете исключение, потому что свойство вашего объекта имеет недопустимое значение, то есть потому, что ваш объект находится в недопустимом состоянии. Правильное исключение для выброса в этом случае - InvalidOperationException, которое определяется как

Исключение, которое выбрасывается, когда вызов метода недопустим для текущего состояния объекта.

(Обратите внимание, что ваш код, находящийся в получателе свойства, считается "вызовом метода".)


Как отступление, даже если значение enum было аргументом, ArgumentException может быть не самым подходящим выбором. Существует InvalidEnumArgumentException, который специально предназначен для использования со значениями перечисления.

...