2017-11-22 9 views
1

私はMetadataType属性クラスを使用してフィールドに属性を適用しようとしています。部分クラスのフィールドにカスタム属性を適用できませんでした。私が従っている例のいくつかはherehereです。C#カスタム属性が適用されていません

私の最後の試合は、私が "いくつかの作業をする"ことが要求されるクラスのすべてのフィールドにフラグを立てることです。

以下の例では、フィールド "Name"にFooAttributeを適用したいとします。実際の生活では、私は生成されたコードを扱っています....

私の非常にわかりやすい例では、私は部分的なクラス - 牛、生成されたコードです。

namespace Models 
{ 
    public partial class Cow 
    { 
     public string Name; 
     public string Colour; 
    } 
} 

FooAttributeを使用するにはNameフィールドが必要です。これを実行しました。

using System; 
using System.ComponentModel.DataAnnotations; 

namespace Models 
{ 
    public class FooAttribute : Attribute { } 

    public class CowMetaData 
    { 
     [Foo] 
     public string Name; 
    } 

    [MetadataType(typeof(CowMetaData))] 
    public partial class Cow 
    { 
     [Foo] 
     public int Weight; 

     public string NoAttributeHere; 
    } 

} 

これはFooAttributeが適用されたWeightフィールド、のための素晴らしい作品 - 私はそれは部分クラスであるため、ことを期待します。名前フィールドはメタデータから属性を取得しませんが、これが本当に必要です。

私は何が欠けているのですか、それとも間違っていますか?

更新:これは、FooAttributeでフィールドを検索する方法です。

public static void ShowAllFieldsWithFooAttribute(Cow cow) 
{ 
    var myFields = cow.GetType().GetFields().ToList(); 
    foreach (var f in myFields) 
    { 
     if (Attribute.IsDefined(f, typeof(FooAttribute))) 
     { 
      Console.WriteLine("{0}", f.Name); 
     } 
    } 
} 

これの結果は次のとおりです。

しかし、私は期待してい:
名前

答えて

0

属性は、メタデータの一部であり、彼らはコンパイル結果に影響されていません。クラスにMetadataType属性を設定しても、すべてのメタデータがクラスのプロパティ/フィールドに拡散されるわけではありません。だから、コード内でMetadataType属性を読み、(それはあなたのケースであるとして一緒か)MetadataType属性で定義されたタイプの代わりに、最初のクラスからメタデータを使用する必要が

サンプルを確認してください:

var fooFields = new Dictionary<FieldInfo, FooAttribute>(); 

    var cowType = typeof (Cow); 
    var metadataType = cowType.GetCustomAttribute<MetadataTypeAttribute>(); 
    var metaFields = metadataType?.MetadataClassType.GetFields() ?? new FieldInfo[0]; 

    foreach (var fieldInfo in cowType.GetFields()) 
    { 
     var metaField = metaFields.FirstOrDefault(f => f.Name == fieldInfo.Name); 
     var foo = metaField?.GetCustomAttribute<FooAttribute>() 
          ?? fieldInfo.GetCustomAttribute<FooAttribute>(); 
     if (foo != null) 
     { 
      fooFields[fieldInfo] = foo; 
     } 
    } 
+0

はい、申し訳ありません、 という事は承知しています。私は質問を更新して、どのように属性を探しているかを示します。 – Damo

+0

これは 'Console.WriteLine(fieldInfo.Name);'に 'fooFields [fieldInfo] = foo;'を変更しただけで、ほぼ同じです。必要なものを手に入れます – ASpirin

+0

これは問題ですが、名前フィールドには適用されません。ところで、この行のMetadataClassTypeのためにあなたのサンプルをコンパイルできません:var metaFields = metadataType?.MetadataClassType.GetFields()??新しいFieldInfo [0]; – Damo

関連する問題