Assembly
=装配件。表示一个程序集,它是一个可重用、无版本冲突并且可自我描述的公共语言运行时应用程序构建基块。(大概就是一组dll?)
命名空间:System.Reflection
程序集:System.Runtime.dll
继承 Object -> Assembly
派生 System.Reflection.Emit.AssemblyBuilder
实现 ICustomAttributeProvider, ISerializable
使用 Assembly 类加载程序集、浏览程序集的元数据和构成部分、发现程序集中包含的类型以及创建这些类型的实例。
属性
属性 | 属性值 | 含义 |
---|---|---|
CodeBase | String | 程序集的位置(按照最初的指定) |
CustomAttributes | IEnumerable | 包含此程序集自定义属性的集合。 |
DefinedTypes | IEnumerable | 定义在此程序集中的类型的集合。 |
EntryPoint | MethodInfo | 表示此程序集入口点的对象。 如果没有找到入口点(例如,此程序集是一个 DLL),则返回 null。 |
EscapedCodeBase | String | URI,包括表示基本代码的转义符。 |
ExportedTypes | IEnumerable | 此程序集中定义的公共类型的集合,这些公共类型在程序集外可见。 |
FullName | String | 程序集的显示名称。 |
GlobalAssemblyCache | Boolean | 如果程序集是从全局程序集缓存加载的,则为true ;否则为 false。 |
HostContext | Int64 | 一个 Int64 值,指示用于加载程序集的主机上下文(如果有)。 |
ImageRuntimeVersion | String | CLR 版本的文件夹名。 这不是完整路径。 |
IsCollectible | Boolean | true 如果此程序集保存在可回收的中 AssemblyLoadContext ,则为; 否则为 false 。 |
IsDynamic | Boolean | 如果当前程序集是在当前进程中动态生成的,则为 true;否则为 false。 |
IsFullyTrusted | Boolean | 如果当前程序集是以完全信任方式加载的,则为 true,否则为 false。 |
Location | String | 包含清单的已加载文件的位置。 如果程序集是从字节数组加载的(例如使用时), Load(Byte[]) 则返回的值为空字符串 ( “” ) 。 |
ManifestModule | Module | 包含程序集清单的模块。 |
Modules | IEnumerable | 包含此程序集中模块的集合。 |
ReflectionOnly | Boolean | 如果程序集被加载到只反射上下文而不是执行上下文中,则为 true;否则为 false。 |
SecurityRuleSet | SecurityRuleSet | CLR 对此程序集强制执行的安全规则集。 |
方法
方法 | 参数 | 返回值 |
---|---|---|
public object? CreateInstance (string typeName); | typeName:要查找类型的 FullName。 | 使用无参数构造函数创建的指定类型的实例;如果未找到 typeName,则为 null。 该类型使用默认联编程序解析,而无需指定区域性或激活属性,并将 BindingFlags 设置为 Public 或 Instance。 |
public static string CreateQualifiedName (string? assemblyName, string? typeName); | assemblyName:程序集的显示名称。typeName:类型的全名。 | 由程序集的显示名称限定的类型的完整名称。 |
public override bool Equals (object? o); | Object:与该实例进行比较的对象。 | 如果与此实例相等,则为true;否则为 false。 |
public static System.Reflection.Assembly? GetAssembly (Type type); | type:一个对象,该对象表示将返回的程序集中的类型。 | 在其中定义指定类型的程序集。 |
public static System.Reflection.Assembly GetCallingAssembly (); | 方法(该方法调用当前正在执行的方法)的 Assembly 对象。 | |
public virtual object[] GetCustomAttributes (bool inherit); | inherit:对于 Assembly 类型的对象,将忽略此参数。 | 包含此程序集自定义属性的数组。 |
public virtual System.Collections.Generic.IList<System.Reflection.CustomAttributeData> GetCustomAttributesData (); | 对象的泛型列表,这些对象表示有关已应用于当前程序集的特性的数据。 | |
public static System.Reflection.Assembly? GetEntryAssembly (); | 程序集是默认应用程序域中的进程可执行文件,或是由 ExecuteAssembly(String) 执行的第一个可执行文件。 当从非托管代码调用时可返回 null。 | |
public static System.Reflection.Assembly GetExecutingAssembly (); | 包含当前执行的代码的程序集。 | |
public virtual Type[] GetExportedTypes (); | 一个数组,表示此程序集中定义并在程序集外可见的类型。 | |
public virtual System.IO.FileStream? GetFile (string name); | name:指定文件的名称。 不包括文件的路径。 | 包含指定文件的流,如果找不到文件则为 null。 |
public virtual System.IO.FileStream[] GetFiles (); | 包含这些文件的流数组。 | |
public virtual Type[] GetForwardedTypes (); | 一个数组,表示此程序集中的转发/传递类型。 | |
public override int GetHashCode (); | 32 位有符号整数哈希代码。 | |
public System.Reflection.Module[] GetLoadedModules (); | 模块的数组。 | |
public virtual System.Reflection.ManifestResourceInfo? GetManifestResourceInfo (string resourceName); | resourceName:区分大小写的资源名称。 | 用关于资源拓扑的信息填充的对象;如果未找到资源,则为 null。 |
public virtual string[] GetManifestResourceNames (); | 包含所有资源名称的数组。 | |
public virtual System.IO.Stream? GetManifestResourceStream (Type type, string name); | type:其命名空间用于确定清单资源名的范围的类型。name:所请求的清单资源的名称(区分大小写)。 | 如果在编译期间没有指定任何资源,或者资源对调用方不可见,则为清单资源或者为 null。 |
public virtual System.Reflection.Module? GetModule (string name); | name:请求的模块的名称。 | 所请求的模块,若未找到该模块则为 null。 |
public System.Reflection.Module[] GetModules (); | 模块的数组。 | |
public virtual System.Reflection.AssemblyName GetName (); | 包含此程序集的完全分析的显示名称的对象。 | |
public virtual void GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context); | info:用序列化信息填充的对象。context:序列化的目标上下文。 | |
public virtual System.Reflection.AssemblyName[] GetReferencedAssemblies (); | 包含此程序集引用的所有程序集的完全分析的显示名称的数组。 | |
public virtual System.Reflection.Assembly GetSatelliteAssembly (System.Globalization.CultureInfo culture, Version? version); | culture:指定的区域性。version:附属程序集的版本。 | 指定的附属程序集。 |
public virtual Type? GetType (string name, bool throwOnError, bool ignoreCase); | name:类型的全名。throwOnError:true 表示在找不到该类型时引发异常;false 则表示返回 null。ignoreCase:如果为 true,则忽略类型名的大小写;否则,为 false。 | 表示指定类的对象。 |
public virtual Type[] GetTypes (); | 一个数组,包含此程序集中定义的所有类型。 | |
public virtual bool IsDefined (Type attributeType, bool inherit); | attributeType:要为此程序集检查的属性类型。inherit:对于该类型的对象,将忽略此自变量。 | 如果已将该属性应用于程序集,则为 true;否则为 false。 |
public static System.Reflection.Assembly Load (byte[] rawAssembly); | rawAssembly:字节数组,它是包含已发出程序集的基于 COFF 的映像。 | 加载的程序集。 |
public static System.Reflection.Assembly LoadFile (string path); | path:要加载的文件的完全限定路径。 | 加载的程序集。 |
public static System.Reflection.Assembly LoadFrom (string assemblyFile, byte[]? hashValue, System.Configuration.Assemblies.AssemblyHashAlgorithm hashAlgorithm); | assemblyFile:包含程序集清单的文件的名称或路径。hashValue:计算所得的哈希代码的值。hashAlgorithm:用于对文件进行哈希处理并生成强名称的哈希算法。 | |
public System.Reflection.Module LoadModule (string moduleName, byte[]? rawModule); | moduleName:模块的名称。 此字符串必须与程序集清单中的文件名对应。rawModule:基于 COFF 映像的字节数组,该数组包含发送的模块或资源。 | 加载的模块。 |
public static System.Reflection.Assembly? LoadWithPartialName (string partialName); | partialName:程序集的显示名称。 | 加载的程序集。 如果未找到 partialName,此方法将返回 null。 |
public static System.Reflection.Assembly ReflectionOnlyLoad (byte[] rawAssembly); | rawAssembly:字节数组,它是包含已发出程序集的基于 COFF 的映像。 | 加载的程序集。 |
public static System.Reflection.Assembly ReflectionOnlyLoadFrom (string assemblyFile); | assemblyFile:包含程序集清单的文件的路径。 | 加载的程序集。 |
public override string ToString (); | 程序集的全名;如果不能确定程序集的全名,则为类名。 | |
public static System.Reflection.Assembly UnsafeLoadFrom (string assemblyFile); | assemblyFile:包含程序集清单的文件的名称或路径。 | 加载的程序集。 |
Asssembly.GetTypes方法代码示例
Assembly SampleAssembly;
SampleAssembly = Assembly.LoadFrom("c:\\Sample.Assembly.dll");
// Obtain a reference to a method known to exist in assembly.
Type[] Alltypes = SampleAssembly.GetTypes();
MethodInfo Method = Alltypes[0].GetMethod("Method1");
// Obtain a reference to the parameters collection of the MethodInfo instance.
ParameterInfo[] Params = Method.GetParameters();
// Display information about method parameters.
// Param = sParam1
// Type = System.String
// Position = 0
// Optional=False
foreach (ParameterInfo Param in Params)
{
Console.WriteLine("Param=" + Param.Name.ToString());
Console.WriteLine(" Type=" + Param.ParameterType.ToString());
Console.WriteLine(" Position=" + Param.Position.ToString());
Console.WriteLine(" Optional=" + Param.IsOptional.ToString());
}
Module
对模块执行反射。
模块是可移植的可执行文件,例如 type.dll 或 application.exe,由一个或多个类和接口组成。 单个模块可包含多个命名空间,而一个命名空间可跨越多个模块。(哦哦,就是一个dll。)
作为一个单元部署的一个或多个模块组成一个程序集。 有关创建包含多个模块的程序集的信息,请参阅多文件程序集。
请注意,.NET Framework 模块与 Visual Basic 中的模块不同,程序员使用它在应用程序中组织函数和子例程。
属性
属性 | 含义 |
---|---|
Assembly | 为此 Module 实例获取适当的 Assembly。 |
CustomAttributes | 获取包含此模型自定义属性的集合。 |
FullyQualifiedName | 获取表示此模块的完全限定名和路径的字符串。 |
MDStreamVersion | 获取元数据流版本。 |
MetadataToken | 获取一个令牌,该令牌用于标识元数据中的模块。 |
ModuleHandle | 获取模块的图柄。 |
ModuleVersionId | 获取可用于区分模块的两个版本的全局唯一标识符 (UUID)。 |
Name | 获取 String,它表示移除了路径的模块名。 |
ScopeName | 获取表示模块名的字符串。 |
class
略
命名空间
命名空间只是说明一个类型是哪个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。
装配件是一个类型居住的地方,那么在一个程序中要使用一个类,就必须告诉编译器这个类住在哪儿,编译器才能找到它,也就是说必须引用该装配件。
那么如果在编写程序的时候,也许不确定这个类在哪里,仅仅只是知道它的名称,就不能使用了吗?答案是可以,这就是反射了,就是在程序运行的时候提供该类型的地址,而去找到它。
反射
反射的定义: 审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。
反射的作用:
- 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。
- 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射。
- 反射主要应用与类库,这些类库需要知道一个类型的定义,以便提供更多的功能。
应用要点:
- 现实应用程序中很少有应用程序需要使用反射类型。
- 使用反射动态绑定需要牺牲性能。
- 有些元数据信息是不能通过反射获取的。
- 某些反射类型是专门为那些clr 开发编译器的开发使用的,所以你要意识到不是所有的反射类型都是适合每个人的。
System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码。
System.Reflection.Assembly | 使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。 |
System.Reflection.MemberInfo | 用于获取有关类 (构造函数、事件、字段、方法和属性) 的所有成员的信息。此类引入所有成员提供的基本功能。 |
System.Reflection.EventInfo | 使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。 |
System.Reflection.FieldInfo | 使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。 |
System.Reflection.MethodBase | 使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。 |
System.Reflection.ConstructorInfo | 使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法来调用特定的构造函数。 |
System.Reflection.MethodInfo | 使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。 |
System.Reflection.PropertyInfo | 使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。 |
System.Reflection.ParameterInfo | 使用ParameterInfo了解参数的名称、数据类型、默认值、是输入参数还是输出参数,以及参数在方法签名中的位置等。GetParameters按顺序返回对象的数组,这些对象表示方法的参数。 |
System.Type |
根据反射获取类型
调用System.Object上声明的方法GetType来获取实例对象的类型对象
在某个方法内,判断传递进来的参数是否实现了某个接口,如果实现了,则调用该接口的一个方法:
public void Process( object processObj )
{
Type t = processsObj.GetType();
if( t.GetInterface(“ITest”) !=null )
…
}
C# typeof() 和 GetType()区别:
- typeof(x)中的x,必须是具体的类名、类型名称等,不可以是变量名称。
- GetType()方法继承自Object,所以C#中任何对象都具有GetType()方法,它的作用和typeof()相同,返回Type类型的当前对象的类型。
比如有一个变量i: Int32 i = new Int32();
– i.GetType()返回值是Int32的类型,但是无法使用typeof(i),因为i是一个变量。
– 如果要使用typeof(),则只能:typeof(Int32),返回的同样是Int32的类型。
通过Type.GetType以及Assembly.GetType方法
通过Type.GetType查找一个类,必须指定它所在的Assembly,或者在已经获得的Assembly实例上面调用GetType。本装配件中类型可以只写类型名称,另一个例外是mscorlib.dll,这个装配件中声明的类型也可以省略装配件名称(.Net装配件编译的时候,默认都引用了mscorlib.dll,除非在编译的时候明确指定不引用它)。
比如:
System.String是在mscorlib.dll中声明的,Type t = Type.GetType(“System.String”)是正确的
System.Data.DataTable是在System.Data.dll中声明的,那么:
Type.GetType(“System.Data.DataTable”)就只能得到空引用。
必须:
Type t = Type.GetType(“System.Data.DataTable,System.Data,Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”);
对于外部调用的动态库应用反射时要用到Assembly.LoadFile(),然后才是获取类型、执行方法等;
当用反射创建当前程序集中对象实例或执行某个类下静态方法时只需通过Type.GetType(“类的完整名”)。
Type.GetType(sClassPath,sAssembly) <=> Assembly.Load(sAssembly).GetType(sClassPath).
根据类型动态创建对象
System.Activator提供了方法来根据类型动态创建对象,比如创建一个DataTable:
Type t = Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
DataTable table = (DataTable)Activator.CreateInstance(t);
根据有参数的构造器创建对象,把参数按照顺序放入一个Object数组中即可:
namespace TestSpace
{
public class TestClass
{
private string _value;
public TestClass(string value)
{
_value=value;
}
}
}
…
Type t = Type.GetType(“TestSpace.TestClass”);
Object[] constructParms = new object[] {“hello”}; //构造器参数
TestClass obj = (TestClass)Activator.CreateInstance(t,constructParms);
获取方法以及动态调用方法
namespace TestSpace
{
public class TestClass
{
private string _value;
public TestClass()
{
}
public TestClass(string value)
{
_value = value;
}
public string GetValue(string prefix)
{
if (_value == null)
return "NULL";
else
return prefix + " : " + _value;
}
public string Value
{
set
{
_value = value;
}
get
{
if (_value == null)
return "NULL";
else
return _value;
}
}
}
}
-----------------------------------
//获取类型信息
Type t = Type.GetType("TestSpace.TestClass");
//构造器的参数
object[] constuctParms = new object[]{"timmy"};
//根据类型创建对象
object dObj = Activator.CreateInstance(t,constuctParms);
//获取方法的信息
MethodInfo method = t.GetMethod("GetValue");
//调用方法的一些标志位,这里的含义是Public并且是实例方法,这也是默认的值
BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
//GetValue方法的参数
object[] parameters = new object[]{"Hello"};
//调用方法,用一个object接收返回值
object returnValue = method.Invoke(dObj,flag,Type.DefaultBinder,parameters,null);
动态创建委托
namespace TestSpace
{
delegate string TestDelegate(string value);
public class TestClass
{
public TestClass()
{
}
public void GetValue(string value)
{
return value;
}
}
}
TestClass obj = new TestClass();
//获取类型,实际上这里也可以直接用typeof来获取类型
Type t = Type.GetType(“TestSpace.TestClass”);
//创建代理,传入类型、创建代理的对象以及方法名称
TestDelegate method = (TestDelegate)Delegate.CreateDelegate(t, obj,”GetValue”);
String returnValue = method(“hello”);