在c#中是否可以从该属性的实例中获取附加到属性的属性,而不知道包含的类?

时间:2016-02-07 14:06:28

标签: c# reflection attributes

标题有点拗口,但在代码中更容易看到:

public struct MyStruct {
    public bool HasAttribute(Attribute attribute) {
        //is there any way to know?
        return ??????;
    }
}

public class MyClass {
    [SomeAttribute]
    MyStruct child;

    public MyClass() {}
}

我已经知道如何通过获取每个属性的属性信息然后调用MyClass.child来查找GetCustomAttributes上的属性,但这仅在我知道struct实例对应于{时才有效{1}}。我想在这里做的是弄清楚结构的特定实例是否附加了属性,而不知道哪个类包含特定实例。

如果您不能为引用类型执行此操作,那将是有意义的,因为实例可以从多个位置引用,但是不应该为值类型定义良好的属性集?

我的用例是创建一个库,通过附加自定义属性可以稍微修改某些对象的行为。如果有一种更惯用的方式来解决这个问题,那么我愿意接受建议。如果允许解决方案,我也愿意进入不安全的环境。

1 个答案:

答案 0 :(得分:2)

抱歉,但那是不可能的。 [SomeAttribute]附加到MyClass字段,与MyStruct完全无关。

由于以下几个原因,无法获取结构的容器

  • 它可能只是一个局部变量或一个临时变量,这意味着结构可以存在于堆栈中或CPU寄存器中。所以,那里没有包含课程。

  • 它可能包含在另一个结构中,这个结构会受到同样的问题。

  • 如果它包含在类中,则必须仅使用struct的地址检索容器类型。如果可能的话,这将涉及非常讨厌的代码。

    想象一下:这样一个结构的地址将是其包含类的地址加上一个偏移量。你必须以某种方式找到容器的vtable的地址(假设你可以从内存地址推断出看起来像vtable的东西)。这将是完全危险/不安全不可靠,您将面临始终获取访问冲突的风险,因为您必须取消引用未知地址。只有无法才能从中获得可靠的东西。

    哦,你还必须这样做,而 GC可能会移动你的容器对象,而不会固定它,因为你首先不知道它的地址

更安全的方法是使用CLR调试API,但此时我会假设你只是不想召唤Cthulhu

我确信还有很多其他方法可以实现您想要的目标,但如果没有更多细节,我就无法更具体。现在,我建议使用其他参数显式初始化您的结构:

public class MyClass {
    MyStruct child = new MyStruct(doThatSpecialThingie: true);
}