1

属性がクラスのプロパティに配置されているかどうかを知る必要があるという問題に遭遇しましたが、実際に取得したのはそのプロパティのインスタンスだけであるため、制限されています(このシナリオでは型は役に立ちません) )。

この問題は、カスタムの ContractResolver を使用して json.net を使用してそのような属性を検出しているという事実に起因しますが、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

マイケル・ブレイが述べたように、それは不可能であり、そうしない理由は完全に理にかなっています。

ただし、私がやろうとしていたことを達成するために、私はそれをなんとかやり遂げましたが、独自のマーカー属性を使用してから ContractResolver オーバーライドを使用する代わりに、json.net 属性を使用しました。

[JsonConverter(typeof(SerializeOnlyWhatIWantOnThisPropertyConverter))]

このようにして、json.net のコードに依存してその仕事を続けながら、プロパティごとにシリアル化したいものを除外することができます。これの欠点は、コンバーターの実装がより冗長でエラーが発生しやすく、TypeNameHandling などの ContractResolver が提供する他の機能を使用できないことです。また、ResolveContract ルートにはキャッシュが組み込まれているため、より効率的であると考えていますが、まだベンチマークを行っていません。

于 2013-07-10T04:03:14.497 に答える