如何从类创建变量列表

时间:2015-07-10 09:39:52

标签: c# wpf class

请帮帮我,我有这类课程:

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;
    };
}

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

我需要一个List,获取变量和注释的名称,但没有值。

感谢您的回复,如果课程很小,那么它运作良好,但如果课程很大,那么它很慢,因为它可以加速这个过程?我有一个非常大的课程,我需要每秒触摸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);
                }
            }
        }

但尽管它运行在一个单独的线程

,但速度很慢

2 个答案:

答案 0 :(得分:1)

您可以使用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);
    }
  }

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

我认为在运行期间无法获得评论(尽管我很乐意对此进行更正)。请参阅:Programmatically get Summary comments at runtime

答案 1 :(得分:1)

  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 PropertyGridPropertyTools以及