关于“反射”的实现

在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>表示。即,在运行时由客户端来确定实际的类型(也就是说,类型可变)。

 

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值