精通C#--类型反射,晚期绑定和基于特性的编程

##反射
1.
.NET中反射是一个运行库类型发现的过程。
使用反射服务,可通过编程使用一个友好的对象模型得到元数据信息。

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.程序集级别特性
程序集或模块级别特性须在命名空间外定义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值