zoukankan      html  css  js  c++  java
  • 泛型反射获取特性值

    泛型反射获取特性值,本文主要是讲述如何使用泛型以及反射来获取属性的特性值的。具体案例如下:

    1、新建控制台项目 GenericReflectionGetsPropertyValues

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace GenericReflectionGetsPropertyValues
    {
    class Program
    {
    static void Main(string[] args)
    {

    }
    }
    }

    2、添加泛型反射获取类型的属性的特性值帮助类 CustomAttributeHelper

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace GenericReflectionGetsPropertyValues
    {
    /// <summary>
    /// 泛型反射获取类型的属性的特性值帮助类
    /// </summary>
    public static class CustomAttributeHelper
    {
    /// <summary>
    /// 缓存字典
    /// </summary>
    public static readonly Dictionary<string, string> cacheKeyValuePairs = new Dictionary<string, string>();

    /// <summary>
    /// 泛型反射获取属性的特性值
    /// </summary>
    /// <typeparam name="T">泛型(特性)</typeparam>
    /// <param name="type">获取属性的特性的类</param>
    /// <param name="func">委托方法</param>
    /// <param name="name">属性名称</param>
    /// <returns>泛型反射获取属性的特性值</returns>
    public static string GetCustomAttributeValue<T>(this Type type, Func<T, string> func, string name) where T : Attribute
    {
    if (func == null || string.IsNullOrEmpty(name))
    {
    return null;
    }
    return GetCustomAttribute(type, func, name);
    }

    /// <summary>
    /// 获取属性的特性值
    /// </summary>
    /// <typeparam name="T">泛型(特性)</typeparam>
    /// <param name="type">获取属性的特性的类</param>
    /// <param name="func">委托方法</param>
    /// <param name="name">属性名称</param>
    /// <returns>反射获取属性的特性值</returns>
    public static string GetCustomAttribute<T>(Type type, Func<T, string> func, string name) where T : Attribute
    {
    string key = GetKey(type, name);
    string returnValue = null;
    if (!cacheKeyValuePairs.ContainsKey(key))
    {
    CacheCustomAttribute(type, func, name);
    if (cacheKeyValuePairs.ContainsKey(key))
    {
    returnValue = cacheKeyValuePairs[key];
    }
    }
    else
    {
    returnValue = cacheKeyValuePairs[key];
    }

    return returnValue;

    }

    /// <summary>
    /// 缓存属性的特性值
    /// </summary>
    /// <typeparam name="T">泛型(特性)</typeparam>
    /// <param name="type">获取属性的特性的类</param>
    /// <param name="func">委托方法</param>
    /// <param name="name">属性名称</param>
    public static void CacheCustomAttribute<T>(Type type, Func<T, string> func, string name) where T : Attribute
    {
    string key = GetKey(type, name);
    string value = GetValue(type, func, name);
    if (!string.IsNullOrEmpty(value))
    {
    if (!cacheKeyValuePairs.ContainsKey(key))
    {
    cacheKeyValuePairs[key] = value;
    }
    }
    }

    /// <summary>
    /// 泛型反射获取特性值
    /// </summary>
    /// <typeparam name="T">特性类型</typeparam>
    /// <param name="type">类型</param>
    /// <param name="func">获取特性值的委托</param>
    /// <param name="name">属性名</param>
    public static string GetValue<T>(Type type, Func<T, string> func, string name) where T : Attribute
    {
    object customAttr = null;
    if (string.IsNullOrEmpty(name))
    {
    customAttr = type.GetCustomAttributes(typeof(T), false).FirstOrDefault();
    }
    else
    {
    var item = type.GetProperty(name);
    if (item != null)
    {
    customAttr = item.GetCustomAttributes(typeof(T), true).FirstOrDefault();
    }
    else
    {
    var field = type.GetField(name);
    if (field != null)
    {
    customAttr = field.GetCustomAttributes(typeof(T), true).FirstOrDefault();
    }
    }
    }

    return customAttr == null ? null : func((T)customAttr);
    }

    /// <summary>
    /// 获取类型中的属性名,作为字典的key
    /// </summary>
    /// <param name="type">类型</param>
    /// <param name="name">名称</param>
    /// <returns>类型中的属性名</returns>
    public static string GetKey(Type type, string name)
    {
    if (string.IsNullOrEmpty(name))
    {
    return type.FullName;
    }
    return type.FullName + "." + name;
    }
    }
    }

    4、添加测试类 TestMyStudent

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace GenericReflectionGetsPropertyValues
    {
    /// <summary>
    /// 测试类
    /// </summary>
    [MyTestAtts("TestMyStudentN", "TestMyStudentP")]
    public class TestMyStudent
    {
    [System.ComponentModel.Description("123")]
    [MyTestAtts("IdN", "IdP")]
    public int Id { get; set; }

    [System.ComponentModel.Description("123")]
    [MyTestAtts("NameN", "NameP")]
    public string Name { get; set; }

    [MyTestAtts("AgeN", "AgeP")]
    public int Age { get; set; }
    }
    }

    5、修改Program

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace GenericReflectionGetsPropertyValues
    {
    class Program
    {
    static void Main(string[] args)
    {
    Console.WriteLine("开始");
    var item = (typeof(TestMyStudent)).GetCustomAttributeValue<MyTestAttsAttribute>(x => x.MyName, nameof(TestMyStudent.Name));//调用测试泛型反射获取属性的特性值
    Console.WriteLine($"反射的特性 Attribute的值: {item}");
    var item2 = (typeof(TestMyStudent)).GetCustomAttributeValue<MyTestAttsAttribute>(x => x.MyName, nameof(TestMyStudent.Name));//测试缓存
    Console.WriteLine($"反射的特性 Attribute的值: {item2}");
    //GetValue<MyAttsAttribute>(typeof(TestMyStudent), x => x.MyName, nameof(TestMyStudent.Name));
    Console.Read();
    }

    /// <summary>
    /// 泛型反射获取特性值
    /// </summary>
    /// <typeparam name="T">特性类型</typeparam>
    /// <param name="type">类型</param>
    /// <param name="func">获取特性值的委托</param>
    /// <param name="name">属性名</param>
    public static void GetValue<T>(Type type, Func<T, string> func, string name) where T : Attribute
    {
    var item = type.GetProperty(name);
    var cus = item.GetCustomAttributes(typeof(T), true).FirstOrDefault();
    Console.WriteLine($"反射 {item.Name}的特性 Attribute的值: {func((T)cus)}");
    }
    }
    }

    6、测试运行结果:

  • 相关阅读:
    Linux 系统的启动过程
    Oracle中row_number()、rank()、dense_rank() 的区别
    Java 动态打印菱形代码之for循环的使用
    Oracle 体系结构chapter2
    Oracle 11g 概述 chaper1
    go解决ctrl+鼠标左键或F12失效问题
    解决unrecognized import path "golang.org/x/sys/windows"问题
    设计规范
    性能分析
    用IDEA导入项目时,项目中的SpringBoot注解无法识别
  • 原文地址:https://www.cnblogs.com/1175429393wljblog/p/10831310.html
Copyright © 2011-2022 走看看