在C#中,反射对于单个对象实现了类环境中的层次检索;对于相关的多个类间(class groups)实现了运行时的动态调用与创建。后者,更多地用于抽象工厂类的对象创建环境中。
基本知识:
用到System.Reflection、System.Activator或System.Object类;
1.读取
(1)单个对象,使用System.Object的GetType方法,即可。
using System;
using System.Reflection;
class TypeObjectFromInstanceApp
{
public static void Main(string[] args)
{
int i = 6;
Type type = i.GetType();
Console.WriteLine(type.Name);
}
}
(2)或,使用System.Type的GetType方法,
public static Type GetType(string name);
public static Type GetType(string name, bool throw);
public static Type GetType(string name, bool throw,bool ignoreCase);
using System;
using System.Reflection;
class TypeObjectFromNameApp
{
public static void DisplaySyntax()
{
Console.WriteLine("\nSyntax: TypeObjectFromName " +
"<typename>\n");
}
public static void DisplayTypeInfo(string typename)
{
try
{
Type type = Type.GetType(typename, true);
Console.WriteLine("\n'{0}' is located in the " +
"module {1}", typename, type.Module);
}
catch(TypeLoadException e)
{
Console.WriteLine("\n'{0}' could not be " +
"located. Did you qualify with a namespace?",
typename);
}
}
public static void Main(string[] args)
{
if (1 != args.Length) DisplaySyntax();
else DisplayTypeInfo(args[0]);
}
}
2.创建
(1)多类间根据需要动态地创建对象,主要是System.Activator类,CreateInstance(type parameter)方法,如下:
using System;
using System.Reflection;
class AbstractFactory
{
public IReflect CreateObject(string classname)
{
IReflect objreflect;
try
{
// Create the type, throwing an exception
// if it can't be created.
System.Type oType = System.Type.GetType(classname,true);
// Create an instance and type-cast it
// to our interface.
objreflect =
(IReflect)System.Activator.CreateInstance(
oType);
}
catch(TypeLoadException e)
{
throw new InvalidOperationException("Type could " +
"not be created. Check innerException " +
"for details", e);
}
return objreflect;
}
};
public interface IReflect
{
string Name { get; }
};
class Reflect1 : IReflect
{
public string Name
{
get { return "Reflect 1"; }
}
};
class Reflect2 : IReflect
{
public string Name
{
get { return "Reflect 2"; }
}
}
class AbstractFactoryApp
{
static void Main(string[] args)
{
callReflection(args[0]);
}
static void callReflection(string strClassName)
{
IReflect objReflect;
AbstractFactory objFactory = new AbstractFactory();
try
{
objReflect = objFactory.CreateObject(strClassName);
Console.WriteLine("You constructed a {0} object",
objReflect.Name);
}
catch(Exception e)
{
Console.WriteLine("ERROR: {0}\n{1}",
e.Message,
(null == e.InnerException ?
"" : e.InnerException.Message));
}
Console.ReadLine();
}
};
(2)全程创建(类型及对象)
// ILGenServer.cs – compile as follows:
// csc /t:library ILGenServer.cs
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace ILGenServer
{
public class CodeGenerator
{
public CodeGenerator()
{
// Get current currentDomain.
currentDomain = AppDomain.CurrentDomain;
// Create assembly in current currentDomain.
assemblyName = new AssemblyName();
assemblyName.Name = "TempAssembly";
assemblyBuilder =
currentDomain.DefineDynamicAssembly(
assemblyName,
AssemblyBuilderAccess.Run);
// Create a module in the assembly.
moduleBuilder =
assemblyBuilder.DefineDynamicModule(
"TempModule");
// Create a type in the module.
typeBuilder =
moduleBuilder.DefineType("TempClass",
TypeAttributes.Public);
// Add a member (a method) to the type.
methodBuilder = typeBuilder.DefineMethod(
"HelloWorld", MethodAttributes.Public,
null, null);
// Generate MSIL.
msil = methodBuilder.GetILGenerator();
msil.EmitWriteLine("Hello World");
msil.Emit(OpCodes.Ret);
// Last "build" step : create type.
type = typeBuilder.CreateType();
}
AppDomain currentDomain;
AssemblyName assemblyName;
AssemblyBuilder assemblyBuilder;
ModuleBuilder moduleBuilder;
TypeBuilder typeBuilder;
MethodBuilder methodBuilder;
ILGenerator msil;
object obj;
Type type;
public Type T
{
get { return this.type; }
}
}; // End of CodeGenerator class
}; // End of ILGenServer namespace
客户端调用上面编译后的dll,如下:
// ILGenClient.cs – compile as follows:
// csc ILGenClient.cs /r:ILGenServer.dll
using System;
using System.Reflection;
using ILGenServer;
public class ILGenClientApp
{
public static void Main()
{
Console.WriteLine("Calling DLL function to generate " +
"a new type and method in memory...");
CodeGenerator gen = new CodeGenerator();
Console.WriteLine("Retrieving dynamically " +
"generated type...");
Type t = gen.T;
if (null != t)
{
Console.WriteLine("Instantiating the new type...");
object o = Activator.CreateInstance(t);
Console.WriteLine("Retrieving the type's " +
"HelloWorld method...");
MethodInfo helloWorld = t.GetMethod("HelloWorld");
if (null != helloWorld)
{
Console.WriteLine("Invoking our dynamically " +
"created HelloWorld method...");
helloWorld.Invoke(o, null);
}
else
{
Console.WriteLine("Could not locate " +
"HelloWorld method");
}
}
else
{
Console.WriteLine("Could not access Type " +
"from server");
}
}
}
小结,如果说“委托”实现了对同构函数(类成员层面)的抽象,那么“反射”提供了对“同性对象”(类层面)全面的动态运行时干预能力。而对于latebinding,则更是直接衍生出了一种新的语法格式,即泛型(generics),一般用<T>表示。即,在运行时由客户端来确定实际的类型(也就是说,类型可变)。
3131

被折叠的 条评论
为什么被折叠?



