2017-03-01 45 views
1

说我有一个泛型类:从通用类的特定实现中排除某个方面?

public abstract class MyClass<T> { 
    // Contents 
} 

我如何指定我的方面的排除只有某些类型的T?我在AssemblyInfo.cs中添加了几个方面,如下所示:

[assembly: LogMethod(AttributePriority = 0, 
        AttributeTargetTypeAttributes = MulticastAttributes.Public, 
        AttributeTargetMemberAttributes = MulticastAttributes.Public, 
        AttributeTargetElements = MulticastTargets.Method)] 

回答

1

不可能以声明方式应用泛型参数过滤。要对方面目标进行高级筛选,您可以覆盖方面的CompileTimeValidate方法并以编程方式进行筛选。

然而,即使这不会是足够在你所描述的情况。假设您已将该方面应用于MyClass<T>中的方法。在编译的这一点上,T还不知道,所以不可能执行检查。具体的T是在代码中的其他地方声明了字段或变量MyClass<T>时已知的。

我可以在你的情况下看到的最好的办法是使纵横instance-scoped和在运行时验证目标类的每个实例。您可以在下面找到这种方法的示例实现。

[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) 
    { 
    } 
}