Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#属性,该属性只能位于具有其他属性的类中的方法上_C#_Attributes_Restriction - Fatal编程技术网

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

C#属性,该属性只能位于具有其他属性的类中的方法上,c#,attributes,restriction,C#,Attributes,Restriction,在C#中,是否可以对一个属性进行限制,使其只能位于具有另一个属性的类中的方法上 [MyClassAttribute] class Foo { [MyMethodAttribute] public string Bar() } 其中“MyMethodAttribute”只能位于具有“MyClassAttribute”的类的内部 可能吗?如果是这样,怎么做呢?用户定义的属性不能这样做。但是我相信编译器有这样的机制,内置的FieldOffsetAttribute使用这种机制 stru

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

[MyClassAttribute]
class Foo
{
    [MyMethodAttribute]
    public string Bar()
}
其中“MyMethodAttribute”只能位于具有“MyClassAttribute”的类的内部


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

用户定义的属性不能这样做。但是我相信编译器有这样的机制,内置的
FieldOffsetAttribute
使用这种机制

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

编辑我认为如果使用类似的方法注入构建过程是可行的。

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

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
类型上的所有属性。

您可能可以使用PostSharp执行此操作:

然后,在属性中,将检查代码类似于以下内容的父类:

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
        }
公共类MyCustomAttribute:属性
{
公共MyCustomAttribute()
{
如果(GetType().CustomAttributes.Count(attr=>attr.AttributeType==typeof(MyCustomClassAttribute))<1)
{
抛出新异常(“需要父属性”)//在此处插入引发编译时错误的Postsharp方法
}

我怀疑这是可能的,属性本身什么也做不了。我不知道有什么编译时方法可以实现这一点。但是,在
MyMethodAttribute
ctor中,您可以通过反射检查托管
MyMethodAttribute
的类上是否存在必需的属性。您可以编写一个Roslyn分析器,在编译时验证这一点如果违反此规则,则显示错误。