代码之家  ›  专栏  ›  技术社区  ›  Schuyler

C#属性,该属性只能位于具有其他属性的类中的方法上

  •  2
  • Schuyler  · 技术社区  · 8 年前

    在C#中,是否可以对一个属性进行限制,使其只能在具有另一个属性的类中的一个方法上?

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

    其中“MyMethodAttribute”只能位于具有“MyClassAttribute”的类的内部。

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

    3 回复  |  直到 8 年前
        1
  •  1
  •   GEEF    8 年前

    如果要尝试对方法属性进行运行时验证,可以执行以下操作:

    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() 使用反射查找 类型

        2
  •  1
  •   MikeDub Kent Boogaart    8 年前

    你也许可以用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
            }
    
        3
  •  0
  •   Cheng Chen    8 年前

    不能对用户定义的属性执行此操作。但我相信编译器有这样的机制 FieldOffsetAttribute 使用这个。

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

    编辑 我认为如果你注入构建过程是可行的,比如 PostSharp .