从通用 class 的特定实现中排除一个方面?
Excluding an aspect from specific implementations of a generic class?
说我有一个通用的 class:
public abstract class MyClass<T> {
// Contents
}
如何为我的 aspect 指定排除特定类型的 T?我在 AssemblyInfo.cs 中添加方面,如下所示:
[assembly: LogMethod(AttributePriority = 0,
AttributeTargetTypeAttributes = MulticastAttributes.Public,
AttributeTargetMemberAttributes = MulticastAttributes.Public,
AttributeTargetElements = MulticastTargets.Method)]
无法以声明方式应用通用参数过滤。对于方面目标的高级过滤,您可以覆盖方面的 CompileTimeValidate 方法并以编程方式进行过滤。
但是,对于您所描述的情况,即使这样也不够。假设您已将方面应用于 MyClass<T>
中的方法。此时在编译中 T 还未知,因此无法执行检查。当 MyClass<T>
的字段或变量在代码的其他地方声明时,具体 T 是已知的。
在您的情况下,我能看到的最佳选择是创建方面 instance-scoped 并在 运行 时间对目标 class 的每个实例进行验证。您可以在下面找到此方法的示例实现。
[PSerializable]
public class LogMethodAttribute : OnMethodBoundaryAspect, IInstanceScopedAspect
{
private bool disabled;
public override void OnEntry( MethodExecutionArgs args )
{
if ( !this.disabled )
{
Console.WriteLine( "OnEntry: {0}({1})", args.Method.Name, args.Arguments.GetArgument( 0 ) );
}
}
public object CreateInstance( AdviceArgs adviceArgs )
{
LogMethodAttribute clone = (LogMethodAttribute) this.MemberwiseClone();
Type type = adviceArgs.Instance.GetType();
if ( type.IsGenericType )
{
Type[] genericArguments = type.GetGenericArguments();
// Filter out targets where T is string.
if ( genericArguments[0] == typeof( string ) )
{
clone.disabled = true;
}
}
return clone;
}
public void RuntimeInitializeInstance()
{
}
}
class Program
{
static void Main( string[] args )
{
var obj1 = new Class1<int>();
obj1.Method1(1);
var obj2 = new Class1<string>();
obj2.Method1("a");
}
}
[LogMethod(AttributeTargetElements = MulticastTargets.Method)]
public class Class1<T>
{
public void Method1(T a)
{
}
}
说我有一个通用的 class:
public abstract class MyClass<T> {
// Contents
}
如何为我的 aspect 指定排除特定类型的 T?我在 AssemblyInfo.cs 中添加方面,如下所示:
[assembly: LogMethod(AttributePriority = 0,
AttributeTargetTypeAttributes = MulticastAttributes.Public,
AttributeTargetMemberAttributes = MulticastAttributes.Public,
AttributeTargetElements = MulticastTargets.Method)]
无法以声明方式应用通用参数过滤。对于方面目标的高级过滤,您可以覆盖方面的 CompileTimeValidate 方法并以编程方式进行过滤。
但是,对于您所描述的情况,即使这样也不够。假设您已将方面应用于 MyClass<T>
中的方法。此时在编译中 T 还未知,因此无法执行检查。当 MyClass<T>
的字段或变量在代码的其他地方声明时,具体 T 是已知的。
在您的情况下,我能看到的最佳选择是创建方面 instance-scoped 并在 运行 时间对目标 class 的每个实例进行验证。您可以在下面找到此方法的示例实现。
[PSerializable]
public class LogMethodAttribute : OnMethodBoundaryAspect, IInstanceScopedAspect
{
private bool disabled;
public override void OnEntry( MethodExecutionArgs args )
{
if ( !this.disabled )
{
Console.WriteLine( "OnEntry: {0}({1})", args.Method.Name, args.Arguments.GetArgument( 0 ) );
}
}
public object CreateInstance( AdviceArgs adviceArgs )
{
LogMethodAttribute clone = (LogMethodAttribute) this.MemberwiseClone();
Type type = adviceArgs.Instance.GetType();
if ( type.IsGenericType )
{
Type[] genericArguments = type.GetGenericArguments();
// Filter out targets where T is string.
if ( genericArguments[0] == typeof( string ) )
{
clone.disabled = true;
}
}
return clone;
}
public void RuntimeInitializeInstance()
{
}
}
class Program
{
static void Main( string[] args )
{
var obj1 = new Class1<int>();
obj1.Method1(1);
var obj2 = new Class1<string>();
obj2.Method1("a");
}
}
[LogMethod(AttributeTargetElements = MulticastTargets.Method)]
public class Class1<T>
{
public void Method1(T a)
{
}
}