1

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

问题来自这样一个事实,即我正在使用自定义 ContractResolver 来检测此类属性,但在使用 ShouldSerialize 谓词的情况下,您从 DefaultContractResolver 获得的只是类型或实例。

我不能使用 Attribute.GetCustomAttributes(type) 因为该属性不在类型上。TypeDescriptor 也没有运气。我在想是否有可能从该实例获取成员信息,以便我可以将其传递给 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
{    
}
4

2 回答 2

0

你是如此接近......只需从类中获取属性(使用反射),然后使用GetCustomAttributes(...)PropertyInfo. 要获取应用于属性的所有属性,请使用:

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);

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

于 2013-07-09T02:41:39.953 回答
0

正如迈克尔·布雷(Michael Bray)所提到的,这是不可能的,为什么不这样做是完全有道理的。

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

[JsonConverter(typeof(SerializeOnlyWhatIWantOnThisPropertyConverter))]

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

于 2013-07-10T04:03:14.497 回答