ㅇ. 포함관계
다음과 같이 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)
{
// 해당Class에Attribute가있는지확인
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);
}
// Method에Annotation있는지확인
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