【问题标题】:Is it possible in c# to get the attributes attached to a property from within the instance of that property, without knowing the containing class?在 c# 中是否可以在不知道包含类的情况下从该属性的实例中获取附加到该属性的属性?
【发布时间】:2016-05-17 05:16:30
【问题描述】:

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

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

public class MyClass {
    [SomeAttribute]
    MyStruct child;

    public MyClass() {}
}

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

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

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

【问题讨论】:

  • 在谈论值类型与引用类型时,我试图在我的问题中解决这个问题。我的理解是,结构的特定实例只能从一个地方引用,因为它是一种值类型。我同意这对课程没有意义。
  • 我认为这是不可能的,因为自定义属性旨在扩展内置属性,例如 publicprivatestatic。自定义属性的行为类似于这些内置属性,就像我们无法知道实例是声明为公共还是私有一样。
  • 谢谢,这说明了问题。你认为有可能找到一个对象的范围吗?对于结构中的代码来确定它是 MyClass 的属性?也许有反射?
  • 为什么需要实例方法HasAttribute来获取非实例相关信息?我的意思是,你不能把实现改成这样吗? HasAttribute(()=>yourObj.MyStructProp)?通过这种方式,您可以操纵表达式以了解道具是否附加了属性
  • 如果我理解正确的话,这需要知道包含结构的对象。上下文是供其他人使用的库,因此不可能拥有此信息。

标签: c# reflection attributes


【解决方案1】:

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

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

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

  • 它可能包含在另一个结构中,这将受到相同问题的影响。

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

    想象一下:这样一个结构的地址将是它的包含类的地址加上一个偏移量。您必须以某种方式找到容器的 vtable 的地址(假设您可以仅从内存地址推断出看起来像 vtable 的内容)。这将是完全危险/不安全的不可靠的,因为你必须取消引用未知地址,所以你会一直冒着访问违规的风险。只是没有办法从中得到可靠的东西。

    哦,你也必须这样做 GC 可能会移动你的容器对象,因为你一开始不知道它的地址,所以不可能固定它.

更明智的方法是使用 CLR 调试 API,但此时我假设您只是 不想召唤 Cthulhu

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

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

【讨论】:

  • 谢谢,这非常有用!我不再直接初始化结构,因为我需要它来支持其他类型的分配。我设置了隐式转换,但是因为我不能重载赋值运算符,所以我不能持久化doThatSpecialThingie 的值。更糟糕的是,因为行为修饰符是一个字符串,所以我不能只创建少数类型作为解决方法。我希望附加一个属性可以让我在分配后保留一些信息。有没有可能在 c# 中完成这样的事情?
  • @Ivanna 好吧,我猜您是XY problem 的典型案例...请阅读该帖子,然后您最好的选择是发布另一个问题,说明完全正确 你需要什么。您应该链接到此问题以显示您尝试过的内容,但问题应该与您的需求本身有关,而不是您认为可以解决的方式。
  • 感谢您的提示,我以前没有听说过,但它是有道理的。我以为我在询问之前尝试寻求解决方案来提供帮助,但我可以看到问题所在。我在这里发布了一个更直接的问题:stackoverflow.com/questions/35255918/…
猜你喜欢
  • 2012-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
相关资源
最近更新 更多