2017-03-01 42 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) 
    { 
    } 
} 
相關問題