7

いくつかのカスタム例外を作成したいとしましょう。そしてもっと欲しいです。新しい例外ごとに新しいクラスを作成できますが、これを行う別の方法はありますか?また、常に新しいクラスを作成する必要がある場合、それらをどこに保存しますか?プロジェクトのルートフォルダでは見栄えがよくありません。

ああ、別の質問:いくつかの例外が同じで、例外の名前が少し変わっている場合、私は何をしていますか?例外Aが次のようになっているとします。

    [Serializable()]
    public class ExceptionA: Exception, ISerializable
    {
        public ExceptionA() : base() { }
        public ExceptionA(string message) : base(message) { }
        public ExceptionA(string message, System.Exception inner) : base(message, inner) { }
        public ExceptionA(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }
}

もう1つは同じで、別の名前です。

    [Serializable()]
    public class ExceptionB: Exception, ISerializable
    {
        public ExceptionB() : base() { }
        public ExceptionB(string message) : base(message) { }
        public ExceptionB(string message, System.Exception inner) : base(message, inner) { }
        public ExceptionB(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }
}

等々。本当に常に新しいクラスを作成して同じコードを貼り付ける必要がありますか?助言がありますか?

4

3 に答える 3

9

新しい例外ごとに新しいクラスを作成できますが、これを行う別の方法はありますか?

いいえ、他に方法はありません。新しい例外タイプを作成する場合は、新しいクラスが必要です。

それらをどこに保管しますか?

それらを使用する必要があるすべてのコードにアクセスできる場所。

いくつかの例外が同じで、例外の名前だけが少し変わっている場合はどうすればよいですか?

はい、まだ新しいクラスを作成する必要がありますが、既存の例外クラスから新しいクラスを派生させることはできます。

于 2012-09-06T11:05:13.880 に答える
2

通常、このようなものでは、プロジェクト/ソリューション全体で使用されるこれらすべてのカスタム例外(または列挙型)を含む単一のプロジェクトまたは名前空間を作成します。

これにより、参照する単一の参照ポイント/アセンブリが得られます。

同じ「外観」の例外についての質問に加えて、「わずかに異なる」名前の他の例外に継承できる基本クラスを作成します。

于 2012-09-06T11:04:50.047 に答える
1

これは、特定の例外タイプをキャッチするためのtry ... catchブロックでのcatch()の動作方法であるため、毎回新しい例外を作成する必要があります。しかし、私はCLRからC#ブックを介して採用された次のアプローチが本当に好きです。

public abstract class ExceptionArgs
{
    public string Message { get { return string.Empty; } }
}

[Serializable]
public class Exception<TExceptionArgs> : Exception, ISerializable
   where TExceptionArgs : ExceptionArgs
{

    private const String c_args = "Args";  // For (de)serialization
    private readonly TExceptionArgs m_args;

    public TExceptionArgs Args { get { return m_args; } }
    public Exception(String message = null, Exception innerException = null)
        : this(null, message, innerException) { }

    public Exception(TExceptionArgs args, String message = null,
       Exception innerException = null)
        : base(message, innerException) { m_args = args; }

    [SecurityPermission(SecurityAction.LinkDemand,
       Flags = SecurityPermissionFlag.SerializationFormatter)]
    protected Exception(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        m_args = (TExceptionArgs)info.GetValue(c_args, typeof(TExceptionArgs));
    }

    [SecurityPermission(SecurityAction.LinkDemand,
       Flags = SecurityPermissionFlag.SerializationFormatter)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(c_args, m_args);
        base.GetObjectData(info, context);
    }

    public override String Message
    {
        get
        {
            String baseMsg = base.Message;
            return (m_args == null) ? baseMsg : baseMsg + " (" + m_args.Message + ")";
        }
    }

    public override Boolean Equals(Object obj)
    {
        Exception<TExceptionArgs> other = obj as Exception<TExceptionArgs>;
        if (obj == null) return false;
        return Object.Equals(m_args, other.m_args) && base.Equals(obj);
    }
    public override int GetHashCode() { return base.GetHashCode(); }
}

これで、次のような例外の新しい引数を作成できるようになります。

public class ExceptionAExceptionArgs : ExceptionArgs
{
    //may add some properties if required here
}

そして、次のような「新しい例外」をキャッチします。

try
{
   //do something here...
}
catch (Exception<ExceptionAExceptionArgs> ex)
{
}

新しい例外を作成するためのコードを少なくするようにします。
注意:基本例外クラスが1つで、子クラスがほとんどない例外の階層を作成する場合、このアプローチは機能しないことに注意してください。
アクセスできるように、必要な場所に例外クラスを配置できますが、それぞれに個別のファイルを作成することをお勧めします。

于 2012-09-06T11:29:05.180 に答える