反射
1.
.NET中反射是一个运行库类型发现的过程。
使用反射服务,可通过编程使用一个友好的对象模型得到元数据信息。
2.
NameSpace: System.Reflection
Assembly
AssemblyName
EventInfo
FieldInfo
MemberInfo
MethodInfo
Module
ParameterInfo
PropertyInfo
System.Type
System.Object.GetType()//
typeof(ClassName)// typeof(MyClass)
Type.GetType()
// Type.GetType(“AssemblyName.ClassName [+ InsertedClassName], [AssemblyName]”, bool bThrowException_, bool bNotIdentifyCase);
// Type.GetType(“AssemblyName.泛型ClassName`参数个数 [+ InsertedClassName], [AssemblyName]”, bool bThrowException_, bool bNotIdentifyCase);
3.动态加载程序集
3.1.
Assembly.Load(Name(, Version=major.minor.build.revision) (, Culture=culture token) (, PublicKeyToken= public key token))
3.2.
AssemblyName asmName;
asmName = new AssemblyName();
asmName.Name = "CarLibrary";
Version v = Version("1.0.0.0");
asmName.Version = v;
Assembly a = Assembly.Load(asmName);
晚期绑定
创建一个给定类型的实例,并在运行时调用其成员。
不需要在编译时知道它存在。
1.
Object Activator.CreateInstance(Type type);
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("***Fun with Late Binding***");
Assembly a = null;
try
{
a = Assembly.Load("CarLibrary");
}
catch(FileNotFoundException ex)
{
Console.WriteLine(ex.Message);
return;
}
if(a != null)
CreateUsingLateBinding(a);
Console.ReadLine();
}
static void CreateUsingLateBinding(Assembly asm)
{
try
{
Type miniVan = asm.GetType("CarLibrary.MiniVan");
// 返回永远为object
object obj = Activator.CreateInstance(miniVan);
Console.WriteLine("Created a {0} using late binding!", obj);
// 触发方法调用
MethodInfo mi = miniVan.GetMethod("TurboBoost");
// 触发类型中方法调用
mi.Invoke(obj, null);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static void InvokeMethodWithArgsUsingLateBinding(Assembly asm)
{
try
{
Type sport = asm.GetType("CarLibrary.SportsCar");
object obj = Activator.CreateInstance(sport);
MethodInfo mi = sport.GetMethod("TurnOnRadio");
mi.Invoke(obj, new object[]{true, 2});
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
.NET特性
1..NET特性是扩展了抽象的System.Attribute基类的类类型。
2.预定义特性的几个例子
[CLSCompliant] 强制被注释项遵从CLS
[DllImport] 允许.NET代码调用任意非托管的C/C++基础类库。
[Obsolete] 标记一个不用的类或成员
[Serializable] 标记一个类或结构可被序列化
[NonSerialized] 指定类或结构中的某个字段不能在序列化过程中被持久化
[ServiceContract]
[Obsolete("Use another vehicle!")]
public class HorseAndBuggy
{
...
}
public sealed class ObsoleteAttribute : Attribute
{
// 给特性提供构造参数时,直到参数被其它类型或外部工具反射后,特性才分配到内存。
// 定义在特性级的字符串数据作为元数据介绍被存储在程序集。
public ObsoleteAttribute(string message, bool error);
public ObsoleteAttribute(string message);
public ObsoleteAttribute();
public bool IsError{ get; }
public string Message{ get; }
}
3.构建自定义特性
public sealed class VehicleDescriptionAttribute : System.Attribute
{
public string Description { get; set; }
public VehicleDescriptionAttribute(string vehicalDescription)
{
Description = vehicalDescription;
}
public VehicleDescriptionAttribute()
{
}
}
[Serializable]
[VehicleDescription(Description="My rocking Harley")]
public class Motorcycle
{
}
[SerializableAttribute]
[ObsoleteAttribute("Use another vehicle!")]
[VehicleDescription("The old gray mare, she ain't what she used to be...")]
public class HorseAndBuggy
{
}
[VehicleDescription("A very long,slow, but feature-rich auto")]
public class Winnebago
{
}
public enum AttributeTargets
{
All,
Assembly,
Class,
Constructor,
Delegate,
Enum,
Event,
Field,
GenericParameter,
Interface,
Method,
Module,
Parameter,
Property,
ReturnValue,
Struct
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
public sealed class VehicleDescriptionAttribute : System.Attribute
{
...
}
4.程序集级别特性
程序集或模块级别特性须在命名空间外定义。