.net reflection

풀그림 2009. 3. 19. 17:51

. 포함관계

다음과 같이 Assemblies안에 포함관계가 있다.

Assemblies> Modules> types> members

 

예제

// Gets the mscorlib assembly in which the object is defined.

Assembly a = typeof(Object).Module.Assembly;

 

// Loads an assembly using its file name.

Assembly a = Assembly.LoadFrom ("MyExe.exe");

// Gets the type names from the assembly.

Type [] types2 = a.GetTypes ();

foreach (Type t in types2)

{

    Console.WriteLine (t.FullName);

}

 

// This program lists all the public constructors

// of the System.String class.

using System;

using System.Reflection;

class ListMembers {

    public static void Main(String[] args) {

        Type t = typeof(System.String);

        Console.WriteLine ("Listing all the public constructors of the {0} type", t);

        // Constructors.

        ConstructorInfo[] ci = t.GetConstructors(BindingFlags.Public | BindingFlags.Instance);

        Console.WriteLine ("//Constructors");

        PrintMembers (ci);

    }

    public static void PrintMembers(MemberInfo [] ms) {

        foreach (MemberInfo m in ms) {

            Console.WriteLine ("{0}{1}", "     ", m);

        }

        Console.WriteLine();

    }

}

 

 

class Mymemberinfo

{

    public static void Main(string[] args)

    {

        Console.WriteLine ("\nReflection.MemberInfo");

        // Gets the Type and MemberInfo.

        Type MyType =Type.GetType("System.IO.File");

        MemberInfo[] Mymemberinfoarray = MyType.GetMembers();

        // Gets and displays the DeclaringType method.

        Console.WriteLine("\nThere are {0} members in {1}.",

            Mymemberinfoarray.Length, MyType.FullName);

        Console.WriteLine("{0}.", MyType.FullName);

        if (MyType.IsPublic)

        {

            Console.WriteLine("{0} is public.", MyType.FullName);

        }

    }

}

 

 

// This code displays information about the GetValue method of FieldInfo.

class MyMethodInfo {

    public static int Main() {

        Console.WriteLine("Reflection.MethodInfo");

        // Gets and displays the Type.

        Type MyType = Type.GetType("System.Reflection.FieldInfo");

        // Specifies the member for which you want type information.

        MethodInfo Mymethodinfo = MyType.GetMethod("GetValue");

        Console.WriteLine(MyType.FullName + "." + Mymethodinfo.Name);

        // Gets and displays the MemberType property.

        MemberTypes Mymembertypes = Mymethodinfo.MemberType;

        if (MemberTypes.Constructor == Mymembertypes) {

            Console.WriteLine("MemberType is of type All");

        }

        else if (MemberTypes.Custom == Mymembertypes) {

            Console.WriteLine("MemberType is of type Custom");

        }

        else if (MemberTypes.Event == Mymembertypes) {

            Console.WriteLine("MemberType is of type Event");

        }

        else if (MemberTypes.Field == Mymembertypes) {

            Console.WriteLine("MemberType is of type Field");

        }

        else if (MemberTypes.Method == Mymembertypes) {

            Console.WriteLine("MemberType is of type Method");

        }

        else if (MemberTypes.Property == Mymembertypes) {

            Console.WriteLine("MemberType is of type Property");

        }

        else if (MemberTypes.TypeInfo == Mymembertypes) {

            Console.WriteLine("MemberType is of type TypeInfo");

        }

        return 0;

    }

}

 

 

 

// This program lists all the members of the

class ListMembers {

    public static void Main(String[] args) {

        // Specifies the class.

        Type t = typeof (System.IO.BufferedStream);

        Console.WriteLine ("Listing all the members (public and non public) of the {0} type", t);

 

        // Lists static fields first.

        FieldInfo [] fi = t.GetFields (BindingFlags.Static |

         BindingFlags.NonPublic | BindingFlags.Public);

        Console.WriteLine ("// Static Fields");

        PrintMembers (fi);

 

        // Static properties.

        PropertyInfo [] pi = t.GetProperties (BindingFlags.Static |

         BindingFlags.NonPublic | BindingFlags.Public);

        Console.WriteLine ("// Static Properties");

        PrintMembers (pi);

 

        // Static events.

        EventInfo [] ei = t.GetEvents (BindingFlags.Static |

         BindingFlags.NonPublic | BindingFlags.Public);

        Console.WriteLine ("// Static Events");

        PrintMembers (ei);

 

        // Static methods.

        MethodInfo [] mi = t.GetMethods (BindingFlags.Static |

         BindingFlags.NonPublic | BindingFlags.Public);

        Console.WriteLine ("// Static Methods");

        PrintMembers (mi);

 

        // Constructors.

        ConstructorInfo [] ci = t.GetConstructors (BindingFlags.Instance |

         BindingFlags.NonPublic | BindingFlags.Public);

        Console.WriteLine ("// Constructors");

        PrintMembers (ci);

 

        // Instance fields.

        fi = t.GetFields (BindingFlags.Instance | BindingFlags.NonPublic |

         BindingFlags.Public);

        Console.WriteLine ("// Instance Fields");

        PrintMembers (fi);

 

        // Instance properites.

        pi = t.GetProperties (BindingFlags.Instance | BindingFlags.NonPublic |

         BindingFlags.Public);

        Console.WriteLine ("// Instance Properties");

        PrintMembers (pi);

 

        // Instance events.

        ei = t.GetEvents (BindingFlags.Instance | BindingFlags.NonPublic |

         BindingFlags.Public);

        Console.WriteLine ("// Instance Events");

        PrintMembers (ei);

 

        // Instance methods.

        mi = t.GetMethods (BindingFlags.Instance | BindingFlags.NonPublic  

         | BindingFlags.Public);

        Console.WriteLine ("// Instance Methods");

        PrintMembers (mi);

 

        Console.WriteLine ("\r\nPress ENTER to exit.");

        Console.Read();

    }

 

    public static void PrintMembers (MemberInfo [] ms) {

        foreach (MemberInfo m in ms) {

            Console.WriteLine ("{0}{1}", "     ", m);

        }

        Console.WriteLine();

    }

}

 

 

// Code for building SimpleType.dll.

using System;

 

namespace Simple_Type

{

    public class MySimpleClass

    {

        public void MyMethod(string str, int i)

        {

            Console.WriteLine("MyMethod parameters: {0}, {1}", str, i);

        }

 

        public void MyMethod(string str, int i, int j)

        {

            Console.WriteLine("MyMethod parameters: {0}, {1}, {2}",

                str, i, j);

        }

    }

}

 

 

using System;

using System.Reflection;

using System.Globalization;

// The Simple Type namespace.

using Simple_Type;

namespace Custom_Binder

{

    class MyMainClass

    {

        static void Main()

        {

            // Get the type of MySimpleClass.

            Type myType = typeof(MySimpleClass);

 

            // Get an instance of MySimpleClass.

            MySimpleClass myInstance = new MySimpleClass();

            MyCustomBinder myCustomBinder = new MyCustomBinder();

 

            // Get the method information for the particular overload

            // being sought.

            MethodInfo myMethod = myType.GetMethod("MyMethod",

                BindingFlags.Public | BindingFlags.Instance,

                myCustomBinder, new Type[] {typeof(string),

                    typeof(int)}, null);

            Console.WriteLine(myMethod.ToString());

           

            // Invoke the overload.

            myType.InvokeMember("MyMethod", BindingFlags.InvokeMethod,

                myCustomBinder, myInstance,

                    new Object[] {"Testing...", (int)32});

        }

    }

 

    //****************************************************

    //  A simple custom binder that provides no

    //  argument type conversion.

    //****************************************************

    class MyCustomBinder : Binder

    {

        public override MethodBase BindToMethod(

            BindingFlags bindingAttr,

            MethodBase[] match,

            ref object[] args,

            ParameterModifier[] modifiers,

            CultureInfo culture,

            string[] names,

            out object state)

        {

            if(match == null)

                throw new ArgumentNullException("match");

            // Arguments are not being reordered.

            state = null;

            // Find a parameter match and return the first method with

            // parameters that match the request.

            foreach(MethodBase mb in match)

            {

                ParameterInfo[] parameters = mb.GetParameters();

 

                if(ParametersMatch(parameters, args))

                    return mb;

            }

            return null;

        }

 

        public override FieldInfo BindToField(BindingFlags bindingAttr,

            FieldInfo[] match, object value, CultureInfo culture)

        {

            if(match == null)

                throw new ArgumentNullException("match");

            foreach(FieldInfo fi in match)

            {

                if(fi.GetType() == value.GetType())

                    return fi;

            }

            return null;

        }

 

        public override MethodBase SelectMethod(

            BindingFlags bindingAttr,

            MethodBase[] match,

            Type[] types,

            ParameterModifier[] modifiers)

        {

            if(match == null)

                throw new ArgumentNullException("match");

 

            // Find a parameter match and return the first method with

            // parameters that match the request.

            foreach(MethodBase mb in match)

            {

                ParameterInfo[] parameters = mb.GetParameters();

                if(ParametersMatch(parameters, types))

                    return mb;

            }

 

            return null;

        }

 

        public override PropertyInfo SelectProperty(

            BindingFlags bindingAttr,

            PropertyInfo[] match,

            Type returnType,

            Type[] indexes,

            ParameterModifier[] modifiers)

        {

            if(match == null)

                throw new ArgumentNullException("match");

            foreach(PropertyInfo pi in match)

            {

                if(pi.GetType() == returnType &&

                    ParametersMatch(pi.GetIndexParameters(), indexes))

                    return pi;

            }

            return null;

        }

 

        public override object ChangeType(

            object value,

            Type myChangeType,

            CultureInfo culture)

        {

            try

            {

                object newType;

                newType = Convert.ChangeType(value, myChangeType);

                return newType;

            }

            // Throw an InvalidCastException if the conversion cannot

            // be done by the Convert.ChangeType method.

            catch(InvalidCastException)

            {

                return null;

            }

        }

 

        public override void ReorderArgumentArray(ref object[] args,

            object state)

        {

            // No operation is needed here because BindToMethod does not

            // reorder the args array. The most common implementation

            // of this method is shown below.

           

            // ((BinderState)state).args.CopyTo(args, 0);

        }

 

        // Returns true only if the type of each object in a matches

        // the type of each corresponding object in b.

        private bool ParametersMatch(ParameterInfo[] a, object[] b)

        {

            if(a.Length != b.Length)

                return false;

            for(int i = 0; i < a.Length; i++)

            {

                if(a[i].ParameterType != b[i].GetType())

                    return false;

            }

            return true;

        }

 

        // Returns true only if the type of each object in a matches

        // the type of each corresponding entry in b.

        private bool ParametersMatch(ParameterInfo[] a, Type[] b)

        {

            if(a.Length != b.Length)

                return false;

            for(int i = 0; i < a.Length; i++)

            {

                if(a[i].ParameterType != b[i])

                    return false;

            }

            return true;

        }

    }

}

 

 

 

public class CustomBinderDriver

{

    public static void Main (string[] arguments)

    {

    Type t = typeof (CustomBinderDriver);

    CustomBinder binder = new CustomBinder();

    BindingFlags flags = BindingFlags.InvokeMethod|BindingFlags.Instance|

        BindingFlags.Public|BindingFlags.Static;

 

    // Case 1. Neither argument coercion nor member selection is needed.

    args = new Object[] {};

    t.InvokeMember ("PrintBob", flags, binder, null, args);

 

    // Case 2. Only member selection is needed.

    args = new Object[] {42};

    t.InvokeMember ("PrintValue", flags, binder, null, args);

 

    // Case 3. Only argument coercion is needed.

    args = new Object[] {"5.5"};

    t.InvokeMember ("PrintNumber", flags, binder, null, args);

    }

 

    public static void PrintBob ()

    {

        Console.WriteLine ("PrintBob");

    }

 

    public static void PrintValue (long value)

    {

        Console.WriteLine ("PrintValue ({0})", value);

    }

    public static void PrintValue (String value)

    {

        Console.WriteLine ("PrintValue\"{0}\")", value);

    }

  

    public static void PrintNumber (double value)

    {

        Console.WriteLine ("PrintNumber ({0})", value);

    }

}

 

 

Type t = typeof(DefaultMemberAttribute);

DefaultMemberAttribute defMem = (DefaultMemberAttribute)Attribute.GetCustomAttribute(Assembly.GetAssembly(t), t);

MemberInfo[] memInfo = t.GetMember(defMem.MemberName);

 

 

MemberInfo[] memInfo = t.GetDefaultMembers();

 

 

MethodInfo m = t.GetMethod ("MyMethod");

ParameterInfo[] ps = m.GetParameters();

for (int i = 0; i < ps.Length; i++) {

    Console.WriteLine("Default Value == {0}", ps[i].DefaultValue);

}

 

 

 

class MainClass

{

public static void Main()

{

    System.Reflection.MemberInfo info = typeof(MyClass);

    object[] attributes = info.GetCustomAttributes();

    for (int i = 0; i < attributes.Length; i ++)

        {

        System.Console.WriteLine(attributes[i]);

        }

    }

}

. 구현한 예제(첨부파일안의 내용)

 

[Att1("Program Class", 0, IsClass=true)]

    public class _Main

    {

        [Att1("Program TestMethod1 Method", 1, IsClass=false)]

        public void TestMethod1()

        {

            System.Console.WriteLine("in Program.TestMethod1()");

        }

        public static void PrintAnnotation(Type type)

        {

            // 해당ClassAttribute가있는지확인

            Att1[] att1s = (Att1[])Attribute.GetCustomAttributes(type, typeof(Att1));

            if (att1s == null)

            {

                Console.WriteLine(">>Class[{0}], Attributes is null", type);

                return;

            }

            else if (att1s.Length == 0)

            {

                Console.WriteLine(">>Class[{0}], Attributes Length is 0", type);

                return;

            }

 

            for (int i = 0; i < att1s.Length; i++)

            {

                Console.WriteLine("***********\r\nClass[{0}]\r\n\tdesc[{1}], level[{2}], isClass[{3}]",

                    type, att1s[i].Description, att1s[i].Level, att1s[i].IsClass);

            }

 

            // MethodAnnotation있는지확인

            MemberInfo[] memberInfos = type.GetMembers();

            //Console.WriteLine("memberInfos.length[{0}]", memberInfos.Length);

 

            Object objectInstance = type.InvokeMember(null,

                BindingFlags.CreateInstance, null, null, new Object[] {});

//            Console.WriteLine("objectInstance[{0}]", objectInstance);

 

            for (int i = 0; i < memberInfos.Length; i++)

            {

                Console.Write("Method[{0}], Annotaion[", memberInfos[i].ToString());

 

                Att1 att1Method = (Att1)Attribute.GetCustomAttribute(memberInfos[i], typeof(Att1));

                if (att1Method == null)

                    Console.WriteLine("X]");

                else

                {

                    Console.WriteLine("O]\r\n\tdesc[{0}], level[{1}], isClass[{2}]",

                        att1Method.Description, att1Method.Level, att1Method.IsClass);

                   

                    Console.WriteLine("\t[실행전]");

                    type.InvokeMember(

                        memberInfos[i].Name,

                        BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod

                        , null, objectInstance, null);

                    Console.WriteLine("\t[실행후]");

                }

            }

        }

 

        public static void Main(string[] args)

        {

            // 현재클래스나같은프로젝트의다른클래스의Annotation정보출력

            PrintAnnotation(typeof(_Main));

            PrintAnnotation(typeof(Example1));

 

            // 외부Assembly를읽어서Annotation정보출력

//            Assembly assembly = Assembly.LoadFile("D:\\Dev\\_Test\\TestAnnotation\\ExampleLibrary\\bin\\Debug\\ExampleLibrary.dll");

            Assembly assembly = Assembly.LoadFrom("D:\\Dev\\_Test\\TestAnnotation\\ExampleLibrary\\bin\\Debug\\ExampleLibrary.dll");

            Type[] types = assembly.GetTypes();

 

            foreach (Type type in types)

            {

                PrintAnnotation(type);

            }

 

            Console.ReadLine();

}

    }

 

Assembly.LoadFile() A.dll을 호출하면 A.dll에서 참조하는 B.dll은 호출할수 없으나,

Assembly.LoadFrom()으로 호출하면 가능

 

. 참조URL

- Reflection Overview

http://msdn.microsoft.com/en-us/library/f7ykdhsy(VS.71).aspx

- Viewing Type Information

http://msdn.microsoft.com/en-us/library/t0cs7xez(VS.71).aspx

- Dynamically Loading and Using Types

http://msdn.microsoft.com/en-us/library/k3a58006(VS.71).aspx

- Accessing Default Members

http://msdn.microsoft.com/en-us/library/zcfck9kw(VS.71).aspx

- Accessing Default Argument Values

http://msdn.microsoft.com/en-us/library/x0acewhc(VS.71).aspx

- Accessing Custom Attributes

http://msdn.microsoft.com/en-us/library/a4a92379(VS.71).aspx

 

Posted by 파이팅야
,