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 属性),但如果你专门计划它,你可能能够得到你想要的东西。你总是必须像这样使用反射。

于 2010-04-03T23:53:23.713 回答