【问题标题】:.net Attributes that handle exceptions - usage on a property accessor.net 处理异常的属性 - 在属性访问器上的使用
【发布时间】:2010-04-03 13:39:04
【问题描述】:

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

梦想的例子:

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

上面的代码显然意义不大,但与我想做的事情很接近。我希望属性集访问器上的属性能够捕获某种类型的异常,然后以某种自定义方式处理它(甚至只是吞下它)。

各位有什么想法吗?

【问题讨论】:

    标签: c# .net exception-handling custom-attributes


    【解决方案1】:

    不,除非您使用 PostSharp 或类似工具,否则这是不可能的。这不是标准的属性特性——而是 ASP.NET MVC 为您添加的东西。您不会得到所有属性。

    【讨论】:

      【解决方案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 属性),但你可能能够得到你想要的如果你特别计划。你总是必须像这样使用反射。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-14
        • 2014-06-10
        • 2011-09-25
        • 2019-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-07
        相关资源
        最近更新 更多