【问题标题】:C# Custom Attributes not being applied未应用 C# 自定义属性
【发布时间】:2017-11-22 00:51:55
【问题描述】:

我正在尝试使用 MetadataType 属性类将属性应用于字段。我无法将自定义属性应用于部分类中的字段。我一直关注的一些例子是herehere

我的最终目标是尝试标记一个类中我需要“做一些工作”的所有字段。

在下面的示例中,我希望“名称”字段应用 FooAttribute。在现实生活中,我正在处理生成的代码......

在我非常做作的例子中,我有一个部分类 - 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 的 Weight 字段非常有用 - 但我希望这是因为它在部分类中。 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);
        }
    }
}

这样的结果是:
重量

但我期待:
名称
重量

【问题讨论】:

    标签: c# custom-attributes metadatatype


    【解决方案1】:

    属性是元数据的一部分,不会影响编译结果。将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;
            }
        }
    

    【讨论】:

    • 是的,对不起,我明白了。我将更新我的问题以显示我是如何寻找该属性的。
    • 这和我提供的几乎一样,只需将fooFields[fieldInfo] = foo; 更改为Console.WriteLine( fieldInfo.Name);,你就会得到你需要的东西
    • 这就是问题所在,自定义属性不适用于名称字段。顺便说一句,由于这一行中的 MetadataClassType,我无法编译您的示例: var metaFields = metadataType?.MetadataClassType.GetFields() ??新字段信息[0];
    • 如果该属性只适合您,而不是像我建议的那样从元数据中读取它。万一它是其他东西要阅读它,它似乎不起作用。顺便说一句,错误是什么?在你的情况下检查metadataType 的类型,我使用的是.Net 4.5.2
    • 对于这个错误,我深表歉意:我再次剪切并粘贴,您的示例工作正常。虽然我仍然不明白为什么我的示例不起作用,但您确实解决了我的问题,谢谢。
    猜你喜欢
    • 2012-02-15
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    相关资源
    最近更新 更多