Поделиться через


CA1064: исключения должны быть открытыми

TypeName

ExceptionsShouldBePublic

CheckId

CA1064

Категория

Microsoft.Design

Критическое изменение

Не критическое

Причина

Исключение, не являющееся открытым, происходит непосредственно от Exception, SystemException или ApplicationException.

Описание правила

Внутренне исключение видно только внутри своей внутренней области. После выхода исключения за пределы внутренней области для перехвата исключения можно использовать только базовое исключение. Если внутреннее исключение унаследовано от Exception, SystemException или ApplicationException, внешний код не имеет достаточных данных для обработки исключения.

Однако если код содержит открытое исключение, которое затем используется в качестве базового для внутреннего исключения, будет разумно предположить, что код сможет правильно обработать базовое исключение. Открытое исключение будет иметь больше данных, чем предоставляется в T:System.Exception, T:System.SystemException или T:System.ApplicationException.

Устранение нарушений

Сделайте исключение открытым или сделайте внутреннее исключение производным от открытого исключения, отличного от Exception, SystemException и ApplicationException.

Отключение предупреждений

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

Пример

Это правило вызывает в первом примере метода исключение FirstCustomException, поскольку класс исключений наследует непосредственно от Exception и является внутренним. Правило не срабатывает для класса SecondCustomException, потому что (хотя класс и является производным от класса Exception) он объявлен как открытый. Третий класс также не запускает правило, так как он не является прямым производным от System.Exception, System.SystemException или System.ApplicationException.

using System;
using System.Runtime.Serialization;

namespace Samples
{
    // Violates this rule
    [Serializable]
    internal class FirstCustomException : Exception
    {
        internal FirstCustomException()
        {
        }

        internal FirstCustomException(string message)
            : base(message)
        {
        }

        internal FirstCustomException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        protected FirstCustomException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }

    // Does not violate this rule because
    // SecondCustomException is public
    [Serializable]
    public class SecondCustomException : Exception
    {
        public SecondCustomException()
        {
        }

        public SecondCustomException(string message)
            : base(message)
        {

        }

        public SecondCustomException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        protected SecondCustomException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }

    // Does not violate this rule because
    // ThirdCustomException it does not derive directly from
    // Exception, SystemException, or ApplicationException
    [Serializable]
    internal class ThirdCustomException : SecondCustomException
    {
        internal ThirdCustomException()
        {
        }

        internal ThirdCustomException(string message)
            : base(message)
        {
        }

        internal ThirdCustomException(string message, Exception innerException)
            : base(message, innerException)
        {
        }


        protected ThirdCustomException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }
}