2016-02-26 45 views
2

在C#中可以对属性设置限制,以便它只能位于具有其他属性的类内的方法上?只能在具有其他属性的类中的方法上的C#属性

[MyClassAttribute] 
class Foo 
{ 
    [MyMethodAttribute] 
    public string Bar() 
} 

“MyMethodAttribute”只能在具有“MyClassAttribute”的类的内部。

这可能吗?如果是这样,该怎么办?

+0

我怀疑这是可能的,属性由自己做没有。 –

+0

你可以用你想要的任何方式编写你的类,属性和方法来限制,我对你的问题有点困惑吗? –

+2

我不知道编译时的方式来实现这一点。但是,在'MyMethodAttribute'中,您可以通过反射检查托管'MyMethodAttribute'的类是否存在必需属性。 – GEEF

回答

1

如果你要试试你的方法的运行时间验证属性,你可以做这样的事情:

public abstract class ValidatableMethodAttribute : Attribute 
{ 
    public abstract bool IsValid(); 
} 

public class MyMethodAtt : ValidatableMethodAttribute 
{ 
    private readonly Type _type; 

    public override bool IsValid() 
    { 
     // Validate your class attribute type here 
     return _type == typeof (MyMethodAtt); 
    } 

    public MyMethodAtt(Type type) 
    { 
     _type = type; 
    } 
} 

[MyClassAtt] 
public class Mine 
{ 
    // This is the downside in my opinion, 
    // must give compile-time type of containing class here. 
    [MyMethodAtt(typeof(MyClassAtt))] 
    public void MethodOne() 
    { 

    } 
} 

然后使用反射来发现系统中的所有ValidatableMethodAttributes,并呼吁他们IsValid()。这不是非常可靠并且相当脆弱,但是这种验证类型可以实现您正在寻找的内容。

或者传递类的类型(Mine),然后在IsValid()中使用反射来查找Mine类型上的所有属性。

0

你不能在用户定义的属性上做到这一点。但是我相信编译器有这样的机制,内置的FieldOffsetAttribute使用这个。

struct MyStruct 
{ 
    [FieldOffset(1)] //compile error, StructLayoutAttribute is required 
    private int _num; 
} 

编辑我认为,如果你注入的建设过程中,使用类似PostSharp这是可行的。

1

您也许能够与PostSharp做到这一点:用类似下面的代码(see: Compile time Validation in this tutorial)

然后在你的属性,将检查父类:

public class MyCustomAttribute : Attribute 
{ 
    public MyCustomAttribute() 
    { 
     if (GetType().CustomAttributes.Count(attr => attr.AttributeType == typeof (MyCustomClassAttribute)) < 1) 
     { 
      throw new Exception("Needs parent attribute") //Insert Postsharp method of raising compile time error here 
     } 
相关问题