获取通用的自定义属性

 陛下今晚由臣来侍寝吧值 发布于 2023-02-13 12:27

我正在创建一个自定义属性。我将在多个类中使用它:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class Display : System.Attribute
{
    public string Name { get; set; }

    public string Internal { get; set; }

}

public class Class1
{
    [Display(Name = "ID")]
    public int ID { get; set; }

    [Display(Name = "Name")]
    public string Title { get; set; }
}

public class Class2
{
    [Display(Name = "ID")]
    public int ID { get; set; }

    [Display(Name = "Name")]
    public string Title { get; set; }
}

这里工作正常,但是我想使其尽可能通用,例如MVC示例:

Class1 class1 = new Class1();
class1.Title.DisplayName () / / returns the value "Name"

我唯一能做的就是生成我的属性的循环,但是我需要告知我的typeof Class1

foreach (var prop in typeof(Class1).GetProperties())
{
    var attrs = (Display[])prop.GetCustomAttributes(typeof(Display), false);
    foreach (var attr in attrs)
    {
        Console.WriteLine("{0}: {1}", prop.Name, attr.Name);
    }
}

有什么办法可以按照我想要的方式进行吗?

1 个回答
  • 您无法完全显示所显示的内容,因为它class1.Title是一个计算结果为字符串的表达式。您正在寻找有关该Title属性的元数据。您可以使用表达式树来编写一些接近的东西。这是一个简短的帮助程序类,可将属性值从表达式树的属性中拉出:

    public static class PropertyHelper
    {
        public static string GetDisplayName<T>(Expression<Func<T, object>> propertyExpression)
        {
            Expression expression;
            if (propertyExpression.Body.NodeType == ExpressionType.Convert)
            {
                expression = ((UnaryExpression)propertyExpression.Body).Operand;
            }
            else
            {
                expression = propertyExpression.Body;
            }
    
            if (expression.NodeType != ExpressionType.MemberAccess)
            {
                throw new ArgumentException("Must be a property expression.", "propertyExpression");
            }
    
            var me = (MemberExpression)expression;
            var member = me.Member;
            var att = member.GetCustomAttributes(typeof(DisplayAttribute), false).OfType<DisplayAttribute>().FirstOrDefault();
            if (att != null)
            {
                return att.Name;
            }
            else
            {
                // No attribute found, just use the actual name.
                return member.Name;
            }
        }
    
        public static string GetDisplayName<T>(this T target, Expression<Func<T, object>> propertyExpression)
        {
            return GetDisplayName<T>(propertyExpression);
        }
    }
    

    这是一些示例用法。请注意,您实际上甚至不需要实例来获取此元数据,但是我包含了一个可能方便的扩展方法。

    public static void Main(string[] args)
    {
        Class1 class1 = new Class1();
        Console.WriteLine(class1.GetDisplayName(c => c.Title));
        Console.WriteLine(PropertyHelper.GetDisplayName<Class1>(c => c.Title));
    }
    

    2023-02-13 12:30 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有