3

asp.net mvc の経験から、例外を処理する属性 (HandleErrorAttribute) を持つことができることをよく知っています。私が知る限り、Controller クラスには、この動作に不可欠な OnException イベントがいくつかあります。ただし、自分のコードで同様のことをしたい:

夢の例:

public String MyProperty
{
    [ExceptionBehaviour(typeof(FormatException), MyExEnum.ClearValue)]
    set
    {
        _thing.prop = Convert.ToThing(value);
    }
}
....

上記のコードは明らかにほとんど意味がありませんが、私がやりたいことに近いものです。プロパティ セット アクセサーの属性で、ある種の例外をキャッチし、カスタムの方法でこれを処理するようにします (または単に飲み込むこともできます)。

アイデアはありますか?

4

2 に答える 2

3

いいえ、PostSharp などを使用しない限り、それは不可能です。これは標準の属性機能ではなく、ASP.NET MVC によって追加されるものです。すべての属性で取得できるわけではありません。

于 2010-04-03T18:58:24.197 に答える
2

属性を追加することはできず、プロパティ/メソッドへのすべての呼び出しに例外処理コードが自動的に追加されます。このためのある種のフレームワークを構築している場合にできることは、実行に型の属性を見て、独自の戦略を実装することです。

たとえば、次の属性があるとします。

public enum ExceptionAction { Throw, ReturnDefault };

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class ExceptionBehaviorAttribute : Attribute
{
    public ExceptionBehaviorAttribute(Type exceptionType, ExceptionAction action)
    {
        this.exceptionType = exceptionType;
        this.action = action;
    }

    public Type ExceptionType { get; private set; }
    public ExceptionAction Action { get; private set; }
}

そして、プロパティをそれで装飾したとしましょう:

public interface IHasValue
{
    int Value { get; }
}

public class MyClass : IHasValue
{
    private string value;

    public int Value
    {
        [ExceptionBehavior(typeof(FormatException),
            ExceptionAction.ReturnDefault)]
        get { return int.Parse(this.value); }
    }
}

特定のコードを記述して、その属性を確認し、目的の動作を実装できます。

public int GetValue(IHasValue obj)
{
    if (obj == null)
        throw new ArgumentNullException("obj");
    Type t = obj.GetType();
    PropertyInfo pi = t.GetProperty("Value",
        BindingFlags.Instance | BindingFlags.Public);
    MethodInfo getMethod = pi.GetGetMethod();
    var exbAttributes = (ExceptionBehaviorAttribute[])
        getMethod.GetCustomAttributes(typeof(ExceptionBehaviorAttribute), false);
    try
    {
        return obj.Value;
    }
    catch (Exception ex)
    {
        var matchAttribute = exbAttributes.FirstOrDefault(a =>
            a.ExceptionType.IsAssignableFrom(ex.GetType()));
        if ((matchAttribute != null) &&
            (matchAttribute.Action == ExceptionAction.ReturnDefault))
        {
            return default(int);
        }
        throw;
    }
}

これを行うべきだと言っているわけではありません。また、これは誰にでもできるコードではなく、属性の使用方法の単なる例です。私がここで実証しようとしているのは、(ほとんどの) 属性はコンパイラの動作を変更できない/変更しない (MVC 属性にも当てはまる)ことですが、具体的に計画すれば、必要なものを取得できる可能性があります。常にこのように Reflection を使用する必要があります。

于 2010-04-03T23:53:23.713 に答える