一:松耦合性 - > 接口定义(object), 而不要定义(具体类型),这样提供的类,改了,而我们的定义的接口不变。
利用反射。
Type type = obj.GetType();
Property property = type.GetPropery("Name");
Object temp = property.GetValue(obj, Flags., null, null,.);
如果有人问你,如何调用一个类的private的方法或访问一个类的私有成员,如果你不知道反射的话,你会告诉他不可以。但是有了反射,这一切都成为可能。我有时候会想,既然使用private来限制访问,为什么又要用反射去破坏这种限制呢?也许可以通过侧面来解释这个问题,如果你要维护类的封装性,那请不要用反射,反射会破坏类的封装性。
但反正某些情况下,又会变得相当地有用,比如你有一个dll,其中很多类被声明为internal,如果你要使用这些类,而又无法修改源代码的话,你就可以使用反射了,最近总结了一下,对反射做了一个封装。由于代码比较简单,没有做注释。using System;using System.Collections.Generic;using System.Text;using System.Reflection;namespace UsefulUtility{ public class Invoker { private static BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.IgnoreCase; public static Type GetType(Assembly asm, string typeFullName) { return asm.GetType(typeFullName); } public static Type GetInnerType(string hiddenTypeName, Type outerType) { Module typeModule = outerType.Module; return typeModule.GetType(hiddenTypeName); } public static MethodInfo GetMethod(Type type, string funcName, Type[] paramTypes) { if (paramTypes != null) return type.GetMethod(funcName, flags, null, paramTypes, null); else return type.GetMethod(funcName, flags); } public static MethodInfo GetMethod(Type type, string funcName) { return GetMethod(type, funcName, null); } public static object CallMethod(object obj, string funcName, params object[] parameters) { Type type = obj.GetType(); MethodInfo method = GetMethod(type, funcName, GetTypesFromObjects(parameters)); return method.Invoke(obj, parameters); } public static object CallStaticMethod(Type type, string funcName, params object[] parameters) { MethodInfo method = GetMethod(type, funcName, GetTypesFromObjects(parameters)); return method.Invoke(null, parameters); } public static object GetProperty(object obj, string propertyName) { return GetProperty(obj, propertyName, null); } public static object GetProperty(object obj, string propertyName, params object[] index) { Type type = obj.GetType(); return type.GetProperty(propertyName, flags).GetValue(obj, index); } public static object GetStaticProperty(Type type, string propertyName) { return GetStaticProperty(type, propertyName, null); } public static object GetStaticProperty(Type type, string propertyName, params object[] index) { return type.GetProperty(propertyName, flags).GetValue(null, index); } public static void SetProperty(object obj, string propertyName, object value) { SetProperty(obj, propertyName, value, null); } public static void SetProperty(object obj, string propertyName, object value, params object[] index) { Type type = obj.GetType(); type.GetProperty(propertyName, flags).SetValue(obj, value, index); } public static void SetStaticProperty(Type type, string propertyName, object value) { SetStaticProperty(type, propertyName, value, null); } public static void SetStaticProperty(Type type, string propertyName, object value, params object[] index) { type.GetProperty(propertyName, flags).SetValue(null, value, index); } public static object GetField(object obj, string fieldName) { Type type = obj.GetType(); return type.GetField(fieldName, flags).GetValue(obj); } public static object GetSaticField(Type type, string fieldName) { return type.GetField(fieldName, flags).GetValue(null); } public static void SetField(object obj, string fieldName, object value) { Type type = obj.GetType(); type.GetField(fieldName, flags).SetValue(obj, value); } public static void SetStaticField(Type type, string fieldName, object value) { type.GetField(fieldName, flags).SetValue(null, value); } private static ConstructorInfo GetConstructor(Type type, Type[] paramTypes) { return type.GetConstructor(paramTypes); } public static object CreateInstance(Type type, Type[] paramTypes, params object[] parameters) { return GetConstructor(type, paramTypes).Invoke(parameters); } public static object CreateInstance(Type type, params object[] parameters) { return GetConstructor(type, GetTypesFromObjects(parameters)).Invoke(parameters); } private static Type[] GetTypesFromObjects(object[] objs) { Type[] types = new Type[objs.Length]; for (int i = 0; i < types.Length; i++) types[i] = objs[i].GetType(); return types; } public static void AddEventHandler(object obj, string eventName, MethodInfo method, object methodOwner) { EventInfo eventInfo = obj.GetType().GetEvent(eventName, flags); Delegate eventDeleg = Delegate.CreateDelegate(eventInfo.EventHandlerType, methodOwner, method); eventInfo.AddEventHandler(obj, eventDeleg); } public static void RemoveEventHandler(object obj, string eventName, MethodInfo method,object methodOwner) { EventInfo eventInfo = obj.GetType().GetEvent(eventName, flags); Delegate eventDeleg = Delegate.CreateDelegate(eventInfo.EventHandlerType, methodOwner, method); eventInfo.RemoveEventHandler(obj, eventDeleg); } }}
下面的代码对上面的一些方法进行测试,由于手头只有一个Fetion SDK.dll的文件,所以就拿他开刀了,实现简单的登录,登录后发送一条测试信息到我的手机,为了安全略去了某些信息。
using System;using System.Collections.Generic;using System.Text;using UsefulUtility;using System.Reflection;namespace ConsoleApplication1{ class Program { static object sdk; static Assembly asm; [STAThread] static void Main(string[] args) { // 载入程序集 asm = Assembly.LoadFrom("Fetion SDK.dll"); // 获取Fetion SDK的类型 Type type = Invoker.GetType(asm, "com.hetaoos.FetionSDK.FetionSDK"); // 实例化sdk sdk = Invoker.CreateInstance(type); // 获取账号管理的属性 object accountManager = Invoker.GetProperty(sdk, "AccountManager"); // 设置用户名和密码 Invoker.CallMethod(accountManager, "FillUserIdAndPassword", new object[] { "手机号码", "飞信密码", false }); // 监听事件 Invoker.AddEventHandler(sdk, "SDK_UserSatusChange", Invoker.GetMethod(typeof(Program), "sdk_SDK_UserSatusChange"), null); // 调用登录方法 Invoker.CallMethod(accountManager, "Login"); } static void Hello() { Console.WriteLine("hello in Hello"); } static void sdk_SDK_UserSatusChange(object sender, EventArgs e) { Console.WriteLine(Invoker.GetProperty(e, "NewStatus")); Console.WriteLine(Invoker.GetSaticField(Invoker.GetType(asm, "Imps.Client.UserAccountStatus"), "Logon")); // 这里用==不好使,要用Equals,不知道为什么 if (Invoker.GetProperty(e, "NewStatus").Equals(Invoker.GetSaticField(Invoker.GetType(asm, "Imps.Client.UserAccountStatus"), "Logon"))) { Console.WriteLine("hello"); object contactControl = Invoker.GetProperty(sdk, "ContactControl"); object sendSMS = Invoker.GetProperty(contactControl, "SendSMS"); Invoker.CallMethod(sendSMS, "SendSMS", "要发送信息的飞信号或手机号码", "hello, a test"); } } }}