11

そうですね、私はこれで完全にばかに見えることを知っていますが、私の脳は今朝ギアを上げていません.

「ダメならこういう例外で返して」って言えるメソッドが欲しいですよね?

たとえば、(そしてこれは機能しません)のようなもの:

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = new Exception(message);
        return ex;
    }

ここで私を混乱させているのは、ジェネリック型が whereのために例外型になることを知っていることです。ただし、 ExceptionExTypeに暗黙的にキャストできないため、コードは失敗します。次のように明示的に変換することもできません。

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = (ExType)(new Exception(message));
        return ex;
    }

それも失敗するので..では、このようなことは可能ですか?私はそれが本当のシンプルになるだろうという強い気持ちを持っていますが、私は古いノギンで厳しい一日を過ごしているので、少し余裕を持ってください:P


アップデート

回答してくれてありがとう、どうやら私は完全な馬鹿ではなかったようです! ;)

OK、VegardSamは、正しい型をインスタンス化できるところまで私を連れて行ってくれましたが、インスタンス化後にメッセージパラメータが読み取り専用であるため、明らかに行き詰まりました。

マットは彼の反応で頭に釘を打ちました。私はこれをテストしましたが、すべて正常に動作します. コード例は次のとおりです。

    static ExType TestException<ExType>(string message) where ExType:Exception, new ()
    {
        ExType ex = (ExType)Activator.CreateInstance(typeof(ExType), message);
        return ex;
    }

甘い!:)

みんなありがとう!

4

5 に答える 5

22

ほとんどの場合、次のように実行できます。

static void TestException<E>(string message) where E : Exception, new()
{
    var e = new E();
    e.Message = message;
    throw e;
}

ただし、Exception.Message は読み取り専用であるため、コンパイルされません。コンストラクターに渡すことによってのみ割り当てることができ、既定のコンストラクター以外のものでジェネリック型を制約する方法はありません。

次のように、リフレクション (Activator.CreateInstance) を使用して、メッセージ パラメーターを使用してカスタム例外タイプを「新しく」する必要があると思います。

static void TestException<E>(string message) where E : Exception
{
    throw Activator.CreateInstance(typeof(E), message) as E;
}

編集おっと、例外をスローするのではなく、例外を返したいことに気付きました。同じ原則が適用されるため、throw ステートメントの回答はそのままにしておきます。

于 2008-09-03T10:15:34.863 に答える
10

このソリューションの唯一の問題は、単一の文字列パラメーターを持つコンストラクターを実装しない Exception のサブクラスを作成できるため、MethodMissingException がスローされる可能性があることです。

static void TestException<E>(string message) where E : Exception, new()
{
    try 
    {
      return Activator.CreateInstance(typeof(E), message) as E;
    } 
    catch(MissingMethodException ex) 
    {
      return new E();
    }
}
于 2008-09-03T10:56:24.733 に答える
1

次のように、スローしたい例外のタイプをインラインでインスタンス化しています。

if (ItemNameIsValid(ItemName, out errorMessage))
    throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
if (null == MyArgument)
    throw new ArgumentNullException("MyArgument is null");
于 2012-02-02T14:25:31.037 に答える
0

代わりに試しましたか:

static T TestException<Exception>(string message)
{}

とにかく、すべてのスロー可能な例外は System.Exception から継承する必要があるため、一般的な制約を入れる必要はないと感じているためです。

ジェネリックは継承された型を受け入れることに注意してください。

于 2008-09-03T10:12:41.703 に答える
-1

すべての例外にはパラメーターなしのコンストラクターがあり、Messageプロパティがあるはずなので、次のように動作するはずです。

static ExType TestException<ExType>(string message) where ExType:Exception
{
    ExType ex = new ExType();
    ex.Message = message;
    return ex;
}

編集:OK、メッセージは読み取り専用なので、代わりにクラスが Exception(string) コンストラクターを実装することを期待する必要があります。

static ExType TestException<ExType>(string message) where ExType:Exception
{
    return new ExType(message);
}
于 2008-09-03T10:13:11.297 に答える