Reflection and Structures

I'm trying to track down any materials, code, books, etc, that cover the topic of dealing with structures via reflection.  This topic appears to be non-existent; nobody talks about it. Just to be clear, By structure I am referring to something akin to the following VB code:

Public Structure MyStructure
   Public FirstName as String
   Public LastName as String
   Public IsActive as Boolean
End Structure

And I am asking for anyone to comment or point me in the right direction where I can find such structures being exposed by Reflection code.  All I have been able to find is cryptic references to "NestedTypes" when enumerating Members of a Type.  Beyond that, I haven't found any additional information on how to further detail nestedtypes (or structures) in order to use them effectively in reflection operations.

I hope this question is reasonable since structures do appear in assemblies either on their own or within classes.

Any help would be appreciated.

~~ May the Darkness protect ye. ~~



Answer this question

Reflection and Structures

  • Ross Goodell

    No problem.  Fortunately translating from C# to VB is pretty easy.  Just changing some keywords, reordering declarations, removing the braces and semicolons.  However if you have some difficulty then you can do what I do.  I build the code into a library, open Reflector and disassembly it back into the language of my choice.  Saves some time for arbitrarily long code blocks.

    My experience with reflection has taught me to rely on the documentation but expect to have to compile some code blocks and dump them to the language of my choice until I get it right.  The compilers make it look easy :}

    Good luck,
    Michael Taylor - 11/22/05

  • Potyos

    Hi Michael,

    You're the only lifeline I've come across on this topic.  I will do my best to translate your code sample to VB.NET, and hopefully learn a lot in the process.

    Thanks again, and I'll let you know what happens once I'm done.

    DarkOasis



  • Dgates123

    A structure is no different than any other base type in .NET such as a class or an interface.  You can distinguish a struct from a class by looking at the IsClass and IsValueType properties of the Type class that describes the type.  For classes IsClass is true.  For structures IsValueType is true.  Note that you should be a little careful here because primitives will also return IsValueType and interfaces might as well so be sure to check the appropriate IsPrimitive and IsInterface properties as well.

    Here is a really simple print program to dump a type's members.  Note that I hacked it together so it doesn't do a really good job but it does demonstrate enumerating a type.

    public static class Print
        {
            public static void PrintType ( Type type )
            {
                Console.WriteLine("{0} {{", GetTypeDecl(type));
                PrintTypeMembers(type);
                Console.WriteLine("}");
            }

            private static string GetAccessibilityString ( MemberInfo member )
            {
                return "public";
            }

            private static string GetTypeDecl ( Type type )
            {
                StringBuilder bldr = new StringBuilder();

                //Accessibility
                bldr.Append(GetAccessibilityString(type));
                bldr.Append(" ");

                //Type
                if (type.IsPrimitive)
                    bldr.Append(type.UnderlyingSystemType.Name);
                else if (type.IsEnum)
                    bldr.Append("enum");
                else if (type.IsValueType)
                    bldr.Append("struct");
                else if (type.IsInterface)
                    bldr.Append("interface");
                else if (type.IsClass)
                {
                    if (type.IsAbstract)
                        bldr.Append("abstract ");
                    if (type.IsSealed)
                        bldr.Append("sealed ");

                    bldr.Append("class");
                };

                bldr.Append(" ");
                bldr.Append(type.Name);

                return bldr.ToString();
            }

            private static void PrintTypeMembers ( Type type )
            {
                //Properties
                foreach(PropertyInfo prop in type.GetProperties())
                {
                    PrintTypeProperty(prop);
                };

                //Methods
                foreach(MethodInfo method in type.GetMethods())
                {
                    PrintTypeMethod(method);
                };

                //Fields
                foreach (FieldInfo field in type.GetFields())
                {
                    PrintTypeField(field);
                };

                //Nested types
                foreach (Type nested in type.GetNestedTypes())
                {
                    PrintType(nested);
                };
            }

            private static void PrintTypeField ( FieldInfo field )
            {
                Console.WriteLine(String.Format("{0} {1} {2};", GetAccessibilityString(field), field.FieldType.Name, field.Name));
            }

            private static void PrintTypeProperty ( PropertyInfo prop )
            {
                Console.Write(String.Format("{0} {1} {2} { ", GetAccessibilityString(prop), prop.PropertyType.Name, prop.Name));
                if (prop.GetGetMethod() != null)
                    Console.Write("get; ");
                if (prop.GetSetMethod() != null)
                    Console.Write("set; ");

                Console.WriteLine("}");
            }

            private static void PrintTypeMethod ( MethodInfo method )
            {
                Console.WriteLine(String.Format("{0} {1} {2} ( );", GetAccessibilityString(method), method.ReturnType.Name, method.Name));
            }
        }

    It works for both normal types and nested types.

    Michael Taylor - 11/22/05

  • tobyxu

    Thanks Michael,

    I'm building a base class which I'll probably name ReflectionBase.  My first take is just to have any derived classes be able to conduct self-analysis to the extend that I can accurately retrieve and identify all public members and simple attributes. 

    Once I gain confidence with that, then I can move on to something more intermediate. For example in a multi-user gaming exercise, it might be useful if *any* data class with non-complex datatypes could prepare its own data transmittal which in turn can reconstruct itself when it reaches its destination.  Thats a mouthful for sure.  So think of it as a self-updating mechanism akin to what the DevExpress folks are accomplishing with Persistent Objects (XPO) product. Thats also why I needed to know if structures can be effectively dealt with via reflection.  Otherwise I would have had to restrict my coding to only target fields and properties.

    Dark


  • Reflection and Structures