C#反射方法扩展

反射是程序猿的好帮手,有了反射你可以少写一半的代码。下面是一些常用的反射扩展方法。

源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace LiLi.Util
{
    public static class ReflectionExtension
    {
        public static IEnumerable<string> Keys(this Type type, BindingFlags? propBindingAttr = null, BindingFlags? fieldBindingAttr = null)
        {
            List<string> result = new List<string>();
            result.AddRange(PropertyKeys(type, propBindingAttr));
            result.AddRange(FieldKeys(type, fieldBindingAttr));
            return result;
        }

        public static IEnumerable<string> PropertyKeys(this Type type, BindingFlags? bindingAttr = null)
        {
            PropertyInfo[] props = bindingAttr.HasValue ? type.GetProperties(bindingAttr.Value) : type.GetProperties();
            return props.Select(x => x.Name);
        }

        public static IEnumerable<string> FieldKeys(this Type type, BindingFlags? bindingAttr = null)
        {
            FieldInfo[] fields = bindingAttr.HasValue ? type.GetFields(bindingAttr.Value) : type.GetFields();
            return fields.Select(x => x.Name);
        }

        public static IDictionary<string, object> KeyValueList(this Type type, object obj, BindingFlags? propBindingAttr = null, BindingFlags? fieldBindingAttr = null)
        {
            Dictionary<string, object> result = new Dictionary<string, object>();
            PropertyInfo[] props = propBindingAttr.HasValue ? type.GetProperties(propBindingAttr.Value) : type.GetProperties();
            Array.ForEach(props, x => result.Add(x.Name, x.GetValue(obj)));
            FieldInfo[] fields = fieldBindingAttr.HasValue ? type.GetFields(fieldBindingAttr.Value) : type.GetFields();
            Array.ForEach(fields, x => result.Add(x.Name, x.GetValue(obj)));
            return result;
        }

        public static IDictionary<string, object> PropertyKeyValueList(this Type type, object obj, BindingFlags? bindingAttr = null)
        {
            Dictionary<string, object> result = new Dictionary<string, object>();
            PropertyInfo[] props = bindingAttr.HasValue ? type.GetProperties(bindingAttr.Value) : type.GetProperties();
            Array.ForEach(props, x => result.Add(x.Name, x.GetValue(obj)));
            return result;
        }

        public static IDictionary<string, object> FieldKeyValueList(this Type type, object obj, BindingFlags? bindingAttr = null)
        {
            Dictionary<string, object> result = new Dictionary<string, object>();
            FieldInfo[] fields = bindingAttr.HasValue ? type.GetFields(bindingAttr.Value) : type.GetFields();
            Array.ForEach(fields, x => result.Add(x.Name, x.GetValue(obj)));
            return result;
        }

        public static bool HasKey(this Type type, string key, BindingFlags? propBindingAttr = null, BindingFlags? fieldBindingAttr = null)
        {
            return type.Keys(propBindingAttr, fieldBindingAttr).Contains(key);
        }

        public static object GetValue(this Type type, string key, object obj, BindingFlags? propBindingAttr = null, BindingFlags? fieldBindingAttr = null)
        {
            IDictionary<string, object> propertyKeyValueList = PropertyKeyValueList(type, obj, propBindingAttr);
            if (propertyKeyValueList.ContainsKey(key))
            {
                return propertyKeyValueList[key];
            }
            IDictionary<string, object> fieldKeyValueList = FieldKeyValueList(type, obj, fieldBindingAttr);
            if (fieldKeyValueList.ContainsKey(key))
            {
                return fieldKeyValueList[key];
            }
            return null;
        }
    }
}

 

测试代码(包含使用示例) :

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using LiLi.Util;
using System.Collections.Generic;
using System.Linq;

namespace LiLi.Util.Test
{
    [TestClass]
    public class ReflectionExtensionTest
    {
        [TestMethod]
        public void TestKeys()
        {
            IEnumerable<string> keys = typeof(Monkey).Keys();
            Assert.IsTrue(keys.SequenceEqual(new List<string> { "MonkeyIsGood", "Name", "LikeFoods", "Age" }));
        }
        
        [TestMethod]
        public void TestPropertyKeys()
        {
            IEnumerable<string> keys = typeof(Monkey).PropertyKeys();
            Assert.IsTrue(keys.SequenceEqual(new List<string> { "MonkeyIsGood", "Name", "LikeFoods"}));
        }

        [TestMethod]
        public void TestFieldKeys()
        {
            IEnumerable<string> keys = typeof(Monkey).FieldKeys();
            Assert.IsTrue(keys.SequenceEqual(new List<string> { "Age" }));
        }

        [TestMethod]
        public void TestKeyValueList()
        {
            IDictionary<string, object> keyValueList = typeof(Monkey).KeyValueList(new Monkey {
                Name = "monkey",
                Age = 3,
                LikeFoods = new string[] { "banana" },
                MonkeyIsGood = false
            });
            Assert.AreEqual("monkey", keyValueList["Name"]);
            Assert.AreEqual(3, keyValueList["Age"]);
            Assert.AreEqual("banana", (keyValueList["LikeFoods"] as string[])[0]);
            Assert.AreEqual(false, keyValueList["MonkeyIsGood"]);
        }

        [TestMethod]
        public void TestPropertyKeyValueList()
        {
            IDictionary<string, object> keyValueList = typeof(Monkey).PropertyKeyValueList(new Monkey
            {
                Name = "monkey",
                Age = 3,
                LikeFoods = new string[] { "banana" },
                MonkeyIsGood = false
            });
            Assert.AreEqual("monkey", keyValueList["Name"]);
            Assert.AreEqual("banana", (keyValueList["LikeFoods"] as string[])[0]);
            Assert.AreEqual(false, keyValueList["MonkeyIsGood"]);
        }

        [TestMethod]
        public void TestFieldKeyValueList()
        {
            IDictionary<string, object> keyValueList = typeof(Monkey).FieldKeyValueList(new Monkey
            {
                Name = "monkey",
                Age = 3,
                LikeFoods = new string[] { "banana" },
                MonkeyIsGood = false
            });
            Assert.AreEqual(3, keyValueList["Age"]);
        }

        [TestMethod]
        public void TestHasKey()
        {
            Assert.IsTrue(typeof(Monkey).HasKey("MonkeyIsGood"));
            Assert.IsFalse(typeof(Monkey).HasKey("MonkeyIsBad"));
        }

        [TestMethod]
        public void TestGetValue()
        {
            Monkey monkey = new Monkey
            {
                Name = "monkey",
                Age = 3,
                LikeFoods = new string[] { "banana" },
                MonkeyIsGood = false
            };
            Assert.AreEqual("monkey", typeof(Monkey).GetValue("Name", monkey));
            Assert.AreEqual(3, typeof(Monkey).GetValue("Age", monkey));
            Assert.AreEqual("banana", (typeof(Monkey).GetValue("LikeFoods", monkey) as string[])[0]);
            Assert.AreEqual(false, typeof(Monkey).GetValue("MonkeyIsGood", monkey));
        }

        private class Animal
        {
            public string Name { get; set; }

            public string[] LikeFoods { get; set; }

            public int Age;

            private string Mystery { get; set; }
        }

        private class Monkey : Animal
        {
            public bool MonkeyIsGood { get; set; }
        }
    }
}
View Code

 

如有高见,欢迎交流与分享:)

转载于:https://www.cnblogs.com/yzbubble/p/7682915.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值