您不能添加属性,并自动在对属性/方法的所有调用周围添加异常处理代码。如果您为此构建某种框架,您可以做的是在运行时查看类型的属性并实施您自己的策略。
例如,假设我们有这个属性:
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 属性),但如果你专门计划它,你可能能够得到你想要的东西。你总是必须像这样使用反射。