您的位置:首页 > 其它

.net类型反射与晚期绑定

2014-08-07 10:45 330 查看

概念

以下仅指.NET中的概念

类型:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。
反射:程序可以访问、检测和修改它本身状态或行为的一种技术。
晚期绑定:在程序运行时,创建一个给定类型的实例,并在运行时调用其成员,而不需要在编译时知道它存在的一种技术。

在理解这些概念之前,最好了解程序集。程序集清单会列出程序集引用的外部程序集和资源,早期绑定的对象只能是内部对象和引用的外部程序集对象。如果想要绑定未引用的外部程序集(可能很难理解这种行为,但它确实在某些方面存在需求,比如工厂模式中创建的对象如果是程序集),只能通过反射技术。

例子

下面这个类(下文中称作ASS类)可以加载外部程序集,显示它的一些信息,同时它的静态函数也能显示一个已有类型的信息。

public class AssemblyInfo
{
private Assembly ass;
public AssemblyInfo(string assemblyURL)
{
ass = Assembly.LoadFrom(assemblyURL);
}
/// <summary>
/// 获取当前程序集
/// </summary>
/// <returns></returns>
public Assembly GetAssembly() { return ass; }

/// <summary>
/// 获取指定类型中的字段
/// </summary>
/// <param name="t"></param>
public static string ListFields(Type t)
{
string retVal = "\n>>>>Fileds\n";
var fieldNames = from f in t.GetFields() select f.Name;
foreach (var fd in fieldNames)
{
retVal += string.Format("->{0}\n", fd);
}
return retVal;
}
/// <summary>
/// 获取指定类型中的属性
/// </summary>
/// <param name="t"></param>
public static string ListProps(Type t)
{
string retVal = "\n>>>>Properties\n";
var propNames = from f in t.GetProperties() select f.Name;
foreach (var pr in propNames)
{
retVal += string.Format("->{0}\n", pr);
}
return retVal;
}
/// <summary>
/// 获取指定类型中的方法
/// </summary>
/// <param name="t"></param>
public static string ListMethod(Type t)
{
string retVal = "\n>>>>Methods\n";
var mts = t.GetMethods();
foreach (var mt in mts)
{
string _retVal = mt.ReturnType.FullName;
string paraInfo = "(";
foreach (var pi in mt.GetParameters())
{
paraInfo += string.Format("{0} {1}", pi.ParameterType, pi.Name);
}
paraInfo += ")";
retVal += string.Format("->{0} {1} {2}\n", _retVal, mt.Name, paraInfo);
}
return retVal;
}
/// <summary>
/// 显示程序集的信息
/// </summary>
/// <returns></returns>
public string showInfo()
{
string retVal = "";
var tps = ass.GetTypes();
foreach (var tp in tps)
{
retVal += string.Format("\n****AssemblyName: {0}",tp.Name);
retVal += ListFields(tp) + ListProps(tp) + ListMethod(tp);
}
return retVal;

}
}

查看系统类型的信息

用它来显示Int结构的信息:

static void Main(string[] args)
{
Type t = typeof(int);
System.Console.Write(AssemblyInfo.ListFields(t));
System.Console.Write(AssemblyInfo.ListProps(t));
System.Console.Write(AssemblyInfo.ListMethod(t));
System.Console.ReadLine();
}


运行之后可以看到int结构中的信息,可以与int的元数据对照查看,增加印象。

加载外部程序集

前一篇文章,编译生成了一个MathFunctions.dll,把它复制到本篇博客项目的bin下,这样可以直接通过ASS类来加载,只需要写一个程序集名,而不需要路径,调用的main方法如下:

static void Main(string[] args)
{
string asName = "";
do
{
System.Console.WriteLine("\n请输入程序集名(包括路径):");
asName = System.Console.ReadLine();
if (asName.ToUpper()=="Q")
{
break;
}
//检测程序集是否存在
if (!File.Exists(asName))
{
System.Console.WriteLine(asName + "不存在");
continue;
}
//读取程序集信息
var ass = new AssemblyInfo(asName);
//显示程序集信息
System.Console.Write(ass.showInfo());
} while (true);
}


在弹出的控制台界面中输入“MathFunctions.dll”,回车后即可看到此dll的内部定义。

晚期绑定

晚期绑定基于反射,前面只能看到未引用的外部程序集的定义,晚期绑定则实现调用外部程序集中的方法。(未完)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: