.net处理exception的属性 – 在属性访问器上使用

我从asp.net mvc经验中知道你可以拥有处理exception的属性(HandleErrorAttribute)。 据我所知,Controller类有一些OnException事件,这可能是这种行为的组成部分。 但是,我想在我自己的代码中做类似的事情:

梦想的例子:

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

上面的代码显然没什么意义,但接近我想做的事情。 我希望属性集访问器上的属性捕获某种类型的exception,然后以某种自定义方式处理它(或者甚至只是吞下它)。

任何想法的家伙?

不,除非您使用PostSharp或类似function,否则这是不可能的。 这不是标准的属性function – 而是ASP.NET MVC为您添加的function。 你没有得到所有属性。

您无法添加属性并自动在所有对属性/方法的调用中添加了exception处理代码。 你能做什么,如果你正在为此构建某种框架,那就是在运行时查看类型的属性并实现自己的策略。

例如,假设我们有这个属性:

 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; } } 

现在我不是说你应该这样做,这不是万无一失的代码,它只是你如何使用属性的一个例子。 我在这里要certificate的是(大多数)属性不能/不会改变编译器行为(也适用于MVC属性),但是如果你专门为它设计,你可能会得到你想要的东西。 你总是必须像这样使用Reflection。