-1

please help me I have a class of this type:

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

How to create a list of the variables from this class, and how I can get comment from variable?

I need a List, get names of variables and comment but no values.

Thank you for your reply, if the class is small then it works well, but if the class is large it is very slow as it is possible to accelerate the process? I have a very big class, and I need to touch it 100 times a second, I touch it, I like this way

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

but it is very slow in spite of the fact that it runs on a separate thread

XmaksasX
  • 81
  • 6

2 Answers2

1

You can use Reflection to get the list of members of the class :

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

Then process the array to get a list of member names.

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

You could recurse into the structure if you wanted field names of base classes. The following code adds field names to one further level (so you would get M.x) - you could convert this to a recursive function if required. Play around with the code to get the results you need.

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

Note that it explicitly does not add all field names for System defined types - you could limit it to checking only types defined in your namespace.

I don't think it is possible to get the comments during run-time (though I am happy to be corrected on that). See : Programmatically get Summary comments at runtime

Community
  • 1
  • 1
PaulF
  • 6,673
  • 2
  • 18
  • 29
  • Thank you very much for your help, well, then I'll get only M and I need X public Point M = new Point(); – XmaksasX Jul 10 '15 at 10:16
1
  1. Since comments are not compiled, your program will need access source code (the Class1.cs file) and you will need a C# parser. Teoretically, you could achieve this using Roslyn, which is new C# compiler, that provide API for this kind of tasks. Visual Studio 2015 uses it to provide editor features like intellisense and code analysys.

  2. Could you modify the classes and add the comments to Description attributes?

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

    then you can get the description at runtime using reflection API:

    FieldInfo.GetCustomAttribute<DescriptionAttribute>()
    

    If you could rewrite your fields to properties, you could use TypeDescriptor class which is more suitable for this kind of tasks. Take a look at project as WPF PropertyGrid or PropertyTools as well

Liero
  • 25,216
  • 29
  • 151
  • 297