未应用 C# 自定义属性
C# Custom Attributes not being applied
我正在尝试使用 MetadataType 属性 class 将属性应用于字段。我无法将自定义属性应用于部分 class 中的字段。我一直关注的一些示例是 here and here.
我的最终目标是尝试标记 class 中我需要 "do some work with" 的所有字段。
在下面的示例中,我希望字段 "Name" 应用 FooAttribute。在现实生活中,我正在处理生成的代码....
在我非常人为的例子中,我有一个部分 class - Cow,它是生成的代码;
namespace Models
{
public partial class Cow
{
public string Name;
public string Colour;
}
}
我需要 Name 字段来使用我的 FooAttribute,所以我这样做了;
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 的权重字段非常有效 - 但我希望如此,因为它在部分 class 中。 Name 字段没有从元数据中获取属性,而这正是我真正需要的。
我错过了什么,还是我完全错了?
更新: 这就是我使用 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);
}
}
}
结果是:
体重
但我很期待:
姓名
体重
属性是元数据的一部分,不会影响编译结果。将 MetadataType
属性设置为 class 不会将所有元数据传播到 class 的 properties/fields。因此,您必须阅读代码中的 MetadataType
属性,并使用 MetadataType
属性中定义的类型的元数据而不是初始 class (或在您的情况下一起使用)
检查样本:
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;
}
}
我正在尝试使用 MetadataType 属性 class 将属性应用于字段。我无法将自定义属性应用于部分 class 中的字段。我一直关注的一些示例是 here and here.
我的最终目标是尝试标记 class 中我需要 "do some work with" 的所有字段。
在下面的示例中,我希望字段 "Name" 应用 FooAttribute。在现实生活中,我正在处理生成的代码....
在我非常人为的例子中,我有一个部分 class - Cow,它是生成的代码;
namespace Models
{
public partial class Cow
{
public string Name;
public string Colour;
}
}
我需要 Name 字段来使用我的 FooAttribute,所以我这样做了;
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 的权重字段非常有效 - 但我希望如此,因为它在部分 class 中。 Name 字段没有从元数据中获取属性,而这正是我真正需要的。
我错过了什么,还是我完全错了?
更新: 这就是我使用 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);
}
}
}
结果是:
体重
但我很期待:
姓名
体重
属性是元数据的一部分,不会影响编译结果。将 MetadataType
属性设置为 class 不会将所有元数据传播到 class 的 properties/fields。因此,您必须阅读代码中的 MetadataType
属性,并使用 MetadataType
属性中定义的类型的元数据而不是初始 class (或在您的情况下一起使用)
检查样本:
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;
}
}