• 泛型反射获取特性值


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

    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、测试运行结果:

  • 相关阅读:
    详细解说仿制QQ列表 展开和收起列表
    带大家一步一步封装聊天键盘(三)新增功能不要错过哟
    带大家一步一步封装一个聊天键盘(二)
    带大家一步一步的封装一个聊天键盘(一)
    iOS中的屏幕适配之Autolayout(初级)
    iOS开发中tableViewCell的悬浮效果
    [Leetcode] 1343. Maximum Product of Splitted Binary Tree | 分裂二叉树的最大乘积
    [Leetcode] 560. Subarray Sum Equals K | 和为K的子数组
    爆炸!iOS资源大礼包(持续更新...)
    Objective-C探究alloc方法的实现
  • 原文地址:https://www.cnblogs.com/1175429393wljblog/p/10831310.html
Copyright © 2020-2023  润新知