使用某个类型的属性的实例获取分配给该属性的属性

本文关键字:属性 获取 分配 实例 类型 | 更新日期: 2023-09-27 18:21:46

我遇到了一个问题,我需要知道属性是否被放置在类的属性上,但我受到了限制,因为实际上我得到的只是该属性的一个实例(在这种情况下,类型没有用处)。

这个问题来自于这样一个事实:我使用json.net使用自定义ContractResolver来检测这些属性,但在使用ShouldSerialize谓词的情况下,从DefaultContractResolver得到的只是一个类型或实例。

我无法使用Attribute.GetCustomAttributes(类型),因为该属性不在该类型上。TypeDescriptor也没有运气。我在想,如果可以从该实例中获取memberinfo,以便将其传递给GetCustomAttributes,这可能吗?你还有别的办法吗?

顺便说一句,我想完成的是在一些属性上放置一个标记属性,这样我的契约解析器就可以只序列化该类型的一些属性,而不是全部属性。我不想把它放在类型本身上,因为有时我想序列化整个对象。为每种类型创建一个契约解析器也是不现实的,因为这将是巨大的。

var instance = new MyClass();
instance.MyProperty = new OtherClass();
// propertyValue is all I get when I'm on the ShouldSerializeMethod
object propertyInstance = instance.MyProperty;
var attributes = Attribute.GetCustomAttributes(propertyInstance.GetType());
// this returns no attributes since the attribute is not on the type but on the property of another type
Console.WriteLine (attributes.Length);
public class MyClass
{
    [MyCustomAttribute]
    public OtherClass MyProperty { get; set; }
}
public class OtherClass
{
    public string Name { get; set; }    
}
public class MyCustomAttribute : Attribute
{    
}

使用某个类型的属性的实例获取分配给该属性的属性

你离我们太近了。。。只需从类中获取属性(使用反射),然后从PropertyInfo中使用GetCustomAttributes(…)。要获得应用于属性的所有属性,请使用:

MyClass obj = new MyClass();
var attList = obj.GetType()
                 .GetProperty("MyProperty")
                 .GetCustomAttributes(true);

或者如果你只想要一个特定的属性类型:'

MyClass obj = new MyClass();
var attList = obj.GetType()
                 .GetProperty("MyProperty")
                 .GetCustomAttributes(typeof(MyCustomAttribute), true);

请注意,没有应用于类的实例的属性这样的东西——属性总是在类本身上。因此,尝试为实例获取自定义属性将是徒劳的。

正如Michael Bray所提到的,这是不可能的,为什么不可能也是完全合理的。

然而,为了完成我要做的事情,我设法做到了,但我没有使用自己的标记属性,然后希望使用ContractResolver覆盖,而是使用了json.net属性:

[JsonConverter(typeof(SerializeOnlyWhatIWantOnThisPropertyConverter))]

通过这种方式,我们可以依靠json.net的代码继续完成它的工作,同时允许我们在每个属性的基础上过滤出我们想要序列化的内容。这样做的缺点是转换器的实现更加冗长和容易出错,并且我们不能使用ContractResolver提供的其他功能,如TypeNameHandling。我也相信ResolveContract路由更高效,因为它有内置的缓存,尽管我还没有做任何基准测试。