如何从类中创建变量列表

本文关键字:创建 变量 列表 | 更新日期: 2023-09-27 18:02:15

请帮帮我,我有一个这样的类:

class Class1
{
    ///<summary>1</summary>
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class Point
    {
        ///<summary>1-1</summary>
        public double x;
    };
    ///<summary>2</summary>
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class Base : Point
    {
        ///<summary>2-1</summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public char[] Name;
        ///<summary>2-2</summary>
        public UInt64 type;
        ///<summary>2-3</summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public char[] Model;
    };
    ///<summary>3</summary>
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class Object : Base
    {
        ///<summary>3-1</summary>
        public int State;
        ///<summary>3-2</summary>
        public double G;
        ///<summary>3-3</summary>
        public float L;
        ///<summary>3-4</summary>
        public Point M = new Point();
        ///<summary>3-4</summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
        public char[] fdsArrNull;
    };
}

如何创建这个类的变量列表,以及如何从变量中获得注释?

我需要一个列表,得到变量和评论的名称,但没有值。

感谢您的回复,如果类是小的,那么它的工作很好,但如果类是大的,它是非常缓慢的,因为它是可能加速的过程?我有一个非常大的类,我需要每秒触摸它100次,我触摸它,我喜欢这样

public static List<KeyValuePair<string, string>> listData_Obj = new List<KeyValuePair<string, string>>();
       private static void Get_data_from_obj()
        {
            FieldInfo[] fields = Obj.GetType().GetFields();
            listData_Obj.Clear();
            foreach (FieldInfo field in fields)
            {
                MN = field.Name;
                if (field.FieldType.Namespace.Equals("System"))
                {
                    if (field.FieldType.Name == "Char[]")
                    {
                        char[] char_field = (char[])field.GetValue(Obj);
                        string str = new string(char_field);
                        listData_Obj.Add(new KeyValuePair<string, string>(MN, str.TrimEnd(''0')));
                    }
                    else
                    {
                        listData_Obj.Add(new KeyValuePair<string, string>(MN, field.GetValue(Obj).ToString()));
                    }
                }
                else
                {
                    var fields_of_field = field.GetValue(Obj);
                    foreach (var field2 in fields_of_field.GetType().GetFields())
                    {
                        if (field2.FieldType.Namespace.Equals("System"))
                        {
                            if (field2.FieldType.Name == "Char[]")
                            {
                                var char_field = (char[])field2.GetValue(fields_of_field);
                                string str = new string(char_field);
                                listData_Obj.Add(new KeyValuePair<string, string>(MN+"."+field2.Name, str.TrimEnd(''0')));
                            }
                            else
                            {
                                listData_Obj.Add(new KeyValuePair<string, string>(MN + "." + field2.Name, field2.GetValue(fields_of_field).ToString()));
                            }
                        }
                        else
                        {
                            var str = MN + "." + field2.Name + ".";
                            recurs(field2, fields_of_field, str);
                        }
                    }
                }
            }
        }
        static void recurs(FieldInfo field, dynamic fields_of_field,string strn)
        {
            var fields_of_field2 = field.GetValue(fields_of_field);
            foreach (var field2 in fields_of_field2.GetType().GetFields())
            {
                if (field2.FieldType.Namespace.Equals("System"))
                {
                    if (field2.FieldType.Name == "Char[]")
                    {
                        var char_field = (char[])field2.GetValue(fields_of_field2);
                        string str = new string(char_field);
                        listData_Obj.Add(new KeyValuePair<string, string>(strn+"."+MN+"."+field2.Name, str.TrimEnd(''0')));
                    }
                    else
                    {
                        listData_Obj.Add(new KeyValuePair<string, string>(strn + "." + MN + "." + field2.Name, field2.GetValue(fields_of_field2).ToString()));
                    }
                }
                else
                {
                    var str1 = strn + MN + "." + field2.Name + ".";
                    recurs(field2, fields_of_field2, str1);
                }
            }
        }

但是它非常慢,尽管它在一个单独的线程上运行

如何从类中创建变量列表

您可以使用Reflection来获取类的成员列表:

  FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Instance);

然后处理数组得到成员名列表。

List<string> mylist = new List<string>();
foreach (var field in fields)
    mylist.Add(field.Name);

如果需要基类的字段名,可以递归到结构中。下面的代码将字段名添加到更深一层(因此您将得到M.x)—如果需要,您可以将其转换为递归函数。修改代码以获得所需的结果。

  List<String> ml = new List<string>();
  foreach (var field in fields)
  {
    String MN = field.Name;
    ml.Add(MN);
    if (field.FieldType.Namespace.Equals("System"))
      continue;
    FieldInfo[] fields2 = field.FieldType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Instance);
    if (fields2.Length == 0)
      continue;
    foreach (var field2 in fields2)
    {
      ml.Add(MN + "." + field2.Name);
    }
  }

请注意,它显式地不添加系统定义类型的所有字段名-您可以将其限制为仅检查在您的命名空间中定义的类型。

我认为不可能在运行时获得注释(尽管我很高兴在这方面得到纠正)。参见:在运行时以编程方式获取摘要注释

  1. 因为注释没有被编译,你的程序将需要访问源代码(Class1.cs文件),你将需要一个c#解析器。理论上,你可以使用Roslyn来实现这一点,这是一个新的c#编译器,为这类任务提供了API。Visual Studio 2015使用它来提供智能感知和代码分析等编辑器特性。

  2. 能否修改类并在Description属性中添加注释?

    [Description("1-1")]
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public double x;
    

    ,那么你可以在运行时使用反射API获得描述:

    FieldInfo.GetCustomAttribute<DescriptionAttribute>()
    

    如果您可以将字段重写为属性,则可以使用更适合此类任务的TypeDescriptor类。看看项目作为WPF PropertyGrid或PropertyTools以及