在c#中,是否可以在不知道包含类的情况下从属性实例中获取附加到属性的属性?
标题有点多,但更容易在代码中看到:在c#中,是否可以在不知道包含类的情况下从属性实例中获取附加到属性的属性?,c#,reflection,attributes,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() {}
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
上的属性,但这只有在我知道struct实例对应于MyClass.child
时才有效。我想在这里做的是弄清楚结构的某个特定实例是否具有附加到它的属性,而不知道哪个类包含该特定实例
如果您不能对引用类型执行此操作,这对我来说是有意义的,因为实例可以从多个位置引用,但是属性集不应该总是为值类型定义好吗
我的用例是创建一个库,通过附加自定义属性可以稍微修改某些对象的行为。如果有更惯用的方法来处理这个问题,那么我愿意接受建议。如果能找到解决方案,我也愿意进入不安全的环境。对不起,这是不可能的
[SomeAttribute]
附加到MyClass
的字段,与MyStruct
完全无关
由于以下几个原因,无法获取结构的容器:
- 它可以是局部变量或临时变量,这意味着该结构可以位于堆栈上或CPU寄存器中。所以,这里没有包含类
- 它可以包含在另一个结构中,这将受到相同问题的影响
- 如果它包含在类中,则必须仅使用结构的地址检索容器类型。如果可能的话,这将涉及非常恶劣的代码 想象一下:这样一个结构的地址将是其包含类的地址加上一个偏移量。您必须以某种方式找到容器vtable的地址(假设您可以仅从内存地址推断vtable的外观)。这将是完全危险/不安全和不可靠的,因为您必须取消对未知地址的引用,所以您将一直面临访问违规的风险。没有办法从中得到可靠的东西 哦,你也必须这样做,因为GC可能会移动你的容器对象,而不可能固定它,因为你一开始不知道它的地址
public class MyClass {
MyStruct child = new MyStruct(doThatSpecialThingie: true);
}
在讨论值类型与引用类型时,我试图在我的问题中解决这个问题。我的理解是,结构的特定实例只能从一个位置引用,因为它是值类型。我同意这对类没有意义。我认为这是不可能的,因为定制属性是为了扩展内置属性而设计的,比如
public
,private
,static
。自定义属性的行为与这些内置属性类似,就像我们无法知道实例是声明为public还是private一样。谢谢,这使它处于透视图中。你认为有可能找到一个对象的范围吗?让结构中的代码确定它是MyClass的属性?可能是反射?为什么需要实例方法HasAttribute来获取与实例无关的信息?我是说,你不能把实现改成这样吗?HasAttribute(()=>yourObj.myStructPro)?通过这种方式,您可以操纵表达式以了解道具是否附加了属性。如果我理解正确,则需要知道包含结构的对象。上下文是供其他人使用的库,因此不可能有此信息。谢谢,这是非常有用的!我不再直接初始化结构,因为我需要它来支持其他类型的赋值。我设置了隐式强制转换,但由于无法重载赋值运算符,因此无法持久化dothattspecialthingie
的值。更糟糕的是,因为行为修饰符是一个字符串,所以我不能仅仅创建一些类型作为解决方法。我希望附加一个属性可以让我在分配任务后保留一些信息。在c#中有可能完成这样的事情吗?@Ivana嗯,我想你是在一个典型的例子中。。。请阅读这篇文章,然后你最好的办法就是再发一个问题,明确说明你需要什么。你应该链接到这个问题来展示你的尝试,但是这个问题应该是关于你的需求本身,而不是关于你认为它可以解决的方式。谢谢你的提示,我以前没有听说过,但这是有意义的。我想我是在帮忙,在提出问题之前,我试图找到一个解决方案,但我能看出问题所在。我在这里发布了一个更直接的问题: