C# 如何根据字符串找到Description特性

Dear200892 2020-07-13 10:40:35
现在有一个集合List<Test>和一个对象B。


List<Test> test = new List<Test>();
foreach (var item in test)
{
//1. 根据test.name查找Description特性等于test.name的属性
}


意思就是说,如果test.name="饱了吗",我就找到对象B里面某个属性的【Description=“饱了吗”】
我想得到这个属性。

除了foreach对象B属性,一个个的判断特性,还有别的办法吗?
...全文
530 点赞 收藏 21
写回复
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dear200892 2020-07-14
引用 21 楼 耗子哭死猫 的回复:

List<PropertyInfo> properties = type.GetProperties(BindingFlags.Public |BindingFlags.NonPublic | BindingFlags.Instance).ToList();
Func<PropertyInfo, bool> filter = a => ((DescriptionAttribute)a.GetCustomAttributes(typeof(DescriptionAttribute),true).FirstOrDefault()).Description== name;
PropertyInfo property = properties.Where(filter).FirstOrDefault();
bool value = Convert.ToBoolean(property.GetValue(software, null));//取值
property.SetValue(software, !value, null);//赋值
结贴给分!
回复
耗子哭死猫 2020-07-14
引用 20 楼 Dear200892 的回复:
[quote=引用 19 楼 耗子哭死猫 的回复:]
比如我集合A当前循环的item.name="微信",根据这个值找到对应[Description("微信")]的属性。[/quote] PropertyInfo[] properties = typeof(ElectricalFireFaultModel).GetProperties(BindingFlags.Public | BindingFlags.Instance); PropertyInfo property = properties.Where(x =>((System.ComponentModel.DescriptionAttribute)x.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true)[0]).Description == "模块地址").FirstOrDefault(); string name = property.Name;
回复
Bridge_go 2020-07-13
这不就是查找么,不遍历好像没其他什么办法
回复
Dear200892 2020-07-13
引用 1 楼 tangyanzhi1111 的回复:
反射你这个 list
不明白,能说清楚点吗?
回复
tangyanzhi1111 2020-07-13
反射你这个 list
回复
Dear200892 2020-07-13
引用 19 楼 耗子哭死猫 的回复:
比如我集合A当前循环的item.name="微信",根据这个值找到对应[Description("微信")]的属性。
回复
耗子哭死猫 2020-07-13
引用 18 楼 Dear200892 的回复:
[quote=引用 17 楼 耗子哭死猫 的回复:]
Description是属性的特性

[Description("微信")]
 public bool WeChat{get;set}
[/quote] 你的意思是通过这个字段的描述获得字段的属性吧。
回复
Dear200892 2020-07-13
引用 17 楼 耗子哭死猫 的回复:
Description是属性的特性

[Description("微信")]
 public bool WeChat{get;set}
回复
耗子哭死猫 2020-07-13
引用 楼主 Dear200892 的回复:
现在有一个集合List<Test>和一个对象B。

List<Test> test = new List<Test>();
foreach (var item in test)
{
      //1. 根据test.name查找Description特性等于test.name的属性
 }
意思就是说,如果test.name="饱了吗",我就找到对象B里面某个属性的【Description=“饱了吗”】 我想得到这个属性。 除了foreach对象B属性,一个个的判断特性,还有别的办法吗?
var ar=test.where(x=>x.name=="饱了吗").ToList(); var ar=test.where(x=>x.name==B.Description).ToList();
回复
能把分给我吗?
回复
Dear200892 2020-07-13
引用 12 楼 一只平凡的骡子 的回复:
看来只能用循环做了。
回复
Dear200892 2020-07-13
引用 13 楼 xuzuning 的回复:
不是任性不任性的问题,以前对象B属性很少,前人就用is。。。else判断了,现在属性在增多,我就想缩减部分代码
回复
xuzuning 2020-07-13
键值对是最基础的结构(表),反查表都需要不简单的算法实现 执着是可贵的,任性就不可取了
回复

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var typeList = GetEnumDescriptionList<Data>();
            // 获取  Key、Value
            foreach (var item in typeList.ToList())
            {
                Console.Write($" Key :{item.Key} ,Value:{item.Value} \n");
            }
            Console.WriteLine();

        }

        public static List<KeyValuePair<string, string>> GetEnumDescriptionList<T>()

        {
            List<KeyValuePair<string, string>> result = new List<KeyValuePair<string, string>>();

            FieldInfo[] fields = typeof(T).GetFields();
            foreach (FieldInfo field in fields)
            {
                object[] attr = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                string description = attr.Length == 0 ? field.Name : ((DescriptionAttribute)attr[0]).Description;
                result.Add(new KeyValuePair<string, string>(field.Name, description));
            }
            return result;

        }
    }
    public class Data
    {
        [Description("名称")]
        public string name;
        [Description("年龄")]
        public int age;
    }
}
回复
Dear200892 2020-07-13
引用 8 楼 以专业开发人员为伍 的回复:
编程对我们来说,不消一颗烟的功夫,而且是心到手到,从不会千方百计去找什么框架来代替自己动手。
我现在就单纯的想根据字符串找到那个特性值所对应的属性。
回复
初学编程的人,有些人好几年都在那里玩儿“增删改查”好几年,然后又玩儿“反射”两三年,期望写出很强大很流行的框架。一个看似很有用的知识,被滥用了其实就过了,因为这其实用在偏向 UI 的工具上,而把过于“万能”的代码用在大系统后台框架上实际上只会劳民伤财、降低启动性能、编译时无法发现错误、难以调试的问题。
回复
引用 6 楼 Dear200892 的回复:
[quote=引用 4 楼 以专业开发人员为伍 的回复:]


请问大佬,除了循环还有什么办法取到呢?[/quote]

编程对我们来说,不消一颗烟的功夫,而且是心到手到,从不会千方百计去找什么框架来代替自己动手。
回复
这个业务逻辑并不是“反射list”而是要反射你的对象 B 的类型。这就好像是你不会搬砖,自然听不懂“小工头”让你“给浴室铺瓷砖”的意思。要了解反射知识才能知道所谓的“foreach”用在你自己工作中实际上能不能行。

实际的系统框架设计中,为了可靠和性能等等考虑,通常会“硬编码”对象和属性的选择信息。例如采用接口继承机制,编译时编译完成了最终代码。而不是去几十万次去让程序查类型架构表来逐一判断自己到底要操作哪一个对象或者属性。但是在给特定用户写一个 UI 工具时,能自动宏代换地识别目标对象目标属性,例如产生一个非常简单对象的属性编辑 Editor 画面,这种噱头很漂亮

回复
Dear200892 2020-07-13
引用 4 楼 以专业开发人员为伍 的回复:
请问大佬,除了循环还有什么办法取到呢?
回复
我给你写个例子。
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
object n = new A();
foreach (var p in n.GetType().GetProperties())
{
var attr = p.GetCustomAttributes(typeof(MyDesc), true);
if (attr.Length > 0 && attr[0] is MyDesc d)
Console.WriteLine($"prop {p.Name} desc s is {d.S}");
p.SetValue(n, 1234);
Console.WriteLine($"prop is {p.GetValue(n)}");
}
Console.WriteLine("..................按任意键结束程序");
Console.ReadKey();
}
}

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class MyDesc : Attribute
{
public MyDesc(bool n, string s)
{
this.L = n;
this.S = s;
}

public string S { get; private set; }

public bool L { get; set; }
}

public class A
{
int _pp;

[MyDesc(true, "aaa")]
public int PP
{
get
{
return _pp;
}
set
{
_pp = value;
}
}
}
}


如果你要面向特定用户设计一个面向 UI 的产品,它应该是好的,能让一个公司卖出一个好产品。如果你要考虑大的服务器系统,那么这类代码是性能和稳定性杀手,能让一个公司倒闭。
回复
发动态
发帖子
C#
创建于2007-09-28

10.4w+

社区成员

.NET技术 C#
申请成为版主
社区公告

全世界最好的语言,没有之一.