最近,身边的不少程序员抱怨NET的变化太快了,觉得跟不上变化,心情很沮丧,有的甚至有放弃编程这个行业的想法.

我这篇文章的主题是[NET 4,3,2,1其实什么也没有变],贯穿本文的例子是如何动态调用方法.本文的目的不是驳斥NET升级的无意义,只是想从一个小的技术点说明变与不变是相对的.当一个新技术出现后,了解它出现的意义,了解它的前身,了解它的后续,比盲目的追从要有用的多.

下面看例子,(注:下面的一组例子只演示了从NET1.0 到NET4.0 中动态调用方法的常用方式,在这里我们不谈性能)

NET4.0 中用dynamic实现动态调用方法

在NET4.0 中可以用dynamic 定义一个对象,然后像在VB6(注不是VB.NET,是VB6.0,VB5.0,VB4.0)中那样访问对象成员.

dynamic 定义的对象,打点没有提示,不管方法名与参数是否错误,编译时都不会报错,只有在运行时找不到方法或参数错误才会报错

很多看了NET4.0中 dynamic人会说NET怎么这么没出息,开始学VB6.0了,

而真正了解VB的确人不会这么说.VB的普及是因为简单,而VB的终结不是因为简单,而是因为功能上的欠缺.

NET在尽量实现汇编,C++强大功能的同时,从尽量使其像VB那样简单.

这就是变改不变是相对,保留汇编,C++的功能与VB的简单,抛弃汇编,C++的繁琐与VB的缺陷.变的是方式,不变的是思想

class Program

{

static void Main(string[] args)

{

object obj = new myClass();

dynamic m =obj;

m.test1(10, 20); //打点没有提示,运行时找不到方法会报错

System.Console.Read();

}

}

class myClass

{

public void test1(int x, int y)

{

int v = x + y;

System.Console.WriteLine(v);

}

}

NET 3.X 中用System.Linq.Expressions.Expression实现动态调用方法

下面的例子是我在NET3.X中常用的一种动态调用用方法的方式

我实现了一个myTool类,用myTool的execute方法可以动态调用其它类的方法,

Linq有两部份内容,一个是集合运算,那是高是数学的内容,另一部分就是Expression

//要被动态执行的类

public class myClass

{

public string myMethod1(string s, int i, object o)

{

return s + i.ToString();

}

public static string myMethod2(string s, int i, object o)

{

return i.ToString() + s;

}

public void myMethod3(string s, int i, object o)

{

Console.WriteLine(s + i.ToString());

}

}

//工具类

sing System.Linq.Expressions;

using System.Reflection;

public static class myTool

{

public static R execute<R, T>(T executeObject, string methodName, object[] parameters)

{

System.Reflection.MethodInfo method = executeObject.GetType().GetMethod(methodName);

Func<object, object[], object> executeDelegate;

executeDelegate = getDelegate(method);

var ro =executeDelegate(executeObject, parameters);

return (R)(ro);

}

private static Func<object, object[], object> getDelegate(MethodInfo methodInfo)

{

ParameterExpression instanceParameter = Expression.Parameter(typeof(object), "instance");

ParameterExpression parametersParameter = Expression.Parameter(typeof(object[]), "parameters");

List<Expression> parameterExpressions = new List<Expression>();

ParameterInfo[] paramInfos = methodInfo.GetParameters();

//-参数

for (int i = 0; i < paramInfos.Length; i++)

{

BinaryExpression be = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));

UnaryExpression ue = Expression.Convert(be, paramInfos[i].ParameterType);

parameterExpressions.Add(ue);

}

//--------------------------------------------------------------------------------------------------------

//-判断是否为静态方法

Expression instanceCast;

if (methodInfo.IsStatic == true)

{

instanceCast = null;

}

else

{

instanceCast = Expression.Convert(instanceParameter, methodInfo.ReflectedType);

}

MethodCallExpression methodCall = Expression.Call(instanceCast, methodInfo, parameterExpressions);

//--------------------------------------------------------------------------------------------------------

//-判断是否为有返回值方法

if (methodCall.Type == typeof(void))

{

Expression<Action<object, object[]>> lambda = Expression.Lambda<Action<object, object[]>>(methodCall, instanceParameter, parametersParameter);

Action<object, object[]> execute = lambda.Compile();

return (instance, parameters) => { execute(instance, parameters); return null; };

}

else

{

UnaryExpression castMethodCall = Expression.Convert(methodCall, typeof(object));

Expression<Func<object, object[], object>> lambda = Expression.Lambda<Func<object, object[], object>>(castMethodCall, instanceParameter, parametersParameter);

return lambda.Compile();

}

//--------------------------------------------------------------------------------------------------------

}

}

//调用

class Program

{

static void Main(string[] args)

{

myClass obj = new myClass();

string ro1 = myTool.execute<string, myClass>(obj, "myMethod1", new object[] { "wxwinter", 123, null });

Console.WriteLine(ro1.ToString());

string ro2 = myTool.execute<string, myClass>(obj, "myMethod2", new object[] { "wxd", 123, null });

Console.WriteLine(ro2.ToString());

myTool.execute<string, myClass>(obj, "myMethod3", new object[] { "lzm", 123, null });

Console.Read();

}

}

NET 2.0 中用泛型实现动态调用方法

下面的例子是我在NET2.0中常用的一种动态调用用方法的方式

我实现了一个myTool类,用myTool的execute方法可以动态调用其它类的方法,

泛型,是NET 2.0 中很重要的内容,如果你看这个例子的代码感到吃力,我的建议是先将泛型理解透了现考虑学NET3.X,NET4.0 的内容

(补充一句,这种方式的执行性能比上例低)

//要被动态执行的类

public class myClass

{

public string myMethod1(string s, int i, object o)

{

return s + i.ToString();

}

public static string myMethod2(string s, int i, object o)

{

return i.ToString() + s;

}

public void myMethod3(string s, int i, object o)

{

Console.WriteLine(s + i.ToString());

}

}

//工具类

public static class myTool

{

public static R execute<R, T>(T executeObject, string methodName, object[] parameters)

{

System.Reflection.MethodInfo method = executeObject.GetType().GetMethod(methodName);

object ro = method.Invoke(executeObject, parameters);

R r = (R)(ro);

return r;

}

}

//调用

class Program

{

static void Main(string[] args)

{

myClass obj = new myClass();

string ro1 = myTool.execute<string,myClass>(obj, "myMethod1", new object[] { "wxwinter", 123, null });

Console.WriteLine(ro1.ToString());

string ro2 = myTool.execute<string, myClass>(obj, "myMethod2", new object[] { "wxd", 123, null });

Console.WriteLine(ro2.ToString());

myTool.execute<string, myClass>(obj, "myMethod3", new object[] { "lzm", 123, null });

Console.Read();

}

}

NET 1.X中用返射实现动态调用方法

下面的例子是我在NET1.1中常用的一种动态调用用方法的方式

我实现了一个myTool类,用myTool的execute方法可以动态调用其它类的方法,

没什么好说的,这是基础

//要被动态执行的类

public class myClass

{

public string myMethod1(string s, int i, object o)

{

return s + i.ToString();

}

public static string myMethod2(string s, int i, object o)

{

return i.ToString() + s;

}

public void myMethod3(string s, int i, object o)

{

Console.WriteLine(s + i.ToString());

}

}

//工具类

public static class myTool

{

public static object execute(object executeObject, string methodName, object[] parameters)

{

System.Reflection.MethodInfo method = executeObject.GetType().GetMethod(methodName);

object ro = method.Invoke(executeObject, parameters);

return ro;

}

}

//调用

class Program

{

static void Main(string[] args)

{

object obj = new myClass();

object ro1 = myTool.execute(obj, "myMethod1", new object[] { "wxwinter", 123, null });

Console.WriteLine(ro1.ToString());

object ro2 = myTool.execute(obj, "myMethod2", new object[] { "wxd", 123, null });

Console.WriteLine(ro2.ToString());

myTool.execute(obj, "myMethod3", new object[] { "lzm", 123, null });

Console.Read();

}

}

总结

变与不变是相对,会Socket的学习TCP很容易,会TCP的学习HTTP很容易,会HTTP的学习WebService很容易,会WebService的学习WCF很容易

Dos下的很多写屏技巧在WPF中还在使用.

VB6.0中用ActivitX 创建的动态网页与现在的Silverlight也有很多相似之处

SQL Server 2005中可以写NET代码,让我想起了FoxBase

NET不变的是在提供更多功能的同时让其使用更简单,而NET变的只是实现这一目标的方式

转载于:https://www.cnblogs.com/leeolevis/archive/2011/03/01/1968370.html

NET 4,3,2,1其实什么也没有变相关推荐

  1. 从言行合一到知行合一

    本篇记录突然的随想,偶尔停留 2022-01-17 rest不只是一个简单的api约束分享一本rest小手册,如何把东西变得 RESTful! 2021-12-06 规划 未来编程.   未来需要什么 ...

  2. 2021-10-27 我与地坛

    2021-10-27 我与地坛 要是有些事我没说,地坛,你别以为是我忘了,我什么也没忘,但是有些事只适合收藏.不能说,也不能想,却又不能忘.它们不能变成语言,它们无法变成语言,一旦变成语言就不再是它们 ...

  3. 系统架构升级要不要上微服务?历“久”弥新微服务——你真的需要升级微服务架构吗

    在 <微服务架构设计模式> 一书中,作者总结了关于微服务的一些"重点",原文如下: 中国企业和开发者对微服务架构的热情让我印象深刻.但如同我给所有客户的忠告一样,我想对 ...

  4. mybatis查询报错:com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from string

    mybatis查询报错: com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from strin ...

  5. 恭喜你发现了宝藏,编程习惯-日积月累

    总结: 条件查询可在数据库层创建queryDto进行统一操作. 代码复用:若有代码重复出现了三次,很大概率可以重构.(三则重构) dto和entity中的赋值操作,可以写成方法放在dto中.(充血模型 ...

  6. springboot项目使用junit4进行单元测试,maven项目使用junit4进行单元测试

    首先,maven项目中引入依赖 <dependency><groupId>junit</groupId><artifactId>junit</ar ...

  7. 苹果设备iphone,ipad,macbook网络连接慢,开机开什么卡什么,一步解决

    苹果电脑网络连接慢,开机开什么卡什么??? 网络上的方法一种种,没有一个适用的? 如果你的macbook也是打开就没网,但有一些软件也能用,就是浏览器加载跑条儿,不妨试试! 系统偏好设置-网络-高级- ...

  8. 力扣解题——求根到叶子节点数字之和

    难度:中等 题目:给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字. 例如,从根到叶子节点路径 1->2->3 代表数字 123. 计算从根到 ...

  9. 使用JPA进行update操作时,报org.springframework.beans.factory.BeanCreationException: Error creating bean with

    使用JPA进行update操作时,报org.springframework.beans.factory.BeanCreationException: Error creating bean with ...

  10. Linux下docker安装配置oracle,oracle创建用户并远程连接,实测可用!

    最近在给同学弄毕业设计的数据库,因为oracle在个人电脑上极不稳定,所以他的电脑数据库崩溃了,这时候我就在docker上为他拉了一个oracle,解决了问题. docker的安装共有以下几步,实测没 ...

最新文章

  1. BZOJ3670 [Noi2014]动物园 【KMP计数】
  2. Java基础知识练习02
  3. 博士申请 | 宾夕法尼亚州立大学招收机器学习/人工智能方向全奖博士
  4. P4395-[BOI2003]Gem气垫车【树形dp,四色定理】
  5. Xshell显示中文乱码问题
  6. livedata mvvm_Android MVVM LiveData数据绑定
  7. linux 删除文件
  8. pyqt5多进程 python_Python 多进程大全
  9. Python读取系统文件夹内所有文件并统计数量
  10. python快速排序函数_两种方法在Python中实现快速排序
  11. 【浏览器强制360网页导航】360导航被强制设成首页如何取消?
  12. ssh 远程执行脚本(自己总结)
  13. React 组件的三种写法总结
  14. linux卸载小企鹅输入法,linux下小企鹅输入法的安装
  15. 性能效率(Performance efficient)弱点度量
  16. java里面com.是什么意思
  17. hiddenlayer安装
  18. ssh登录极路由后台_使用小米路由3G,让普通打印机变成网络打印机
  19. 埃及分数拆分——IDA*
  20. 机器学习-神经网络为什么需要非线性(激活函数)

热门文章

  1. 毕业半年(工作一年)
  2. 深度剖析 Linux cp 命令的秘密
  3. uniAPP实现单页面横竖屏切换
  4. vue前后端分离项目打包成app,部署成移动端
  5. 删除后别人的微信号变成wxid_怎样找回删除的微信好友?不用ROOT不用数据恢复软件!而且免费!...
  6. 天涯社区“诚信认证费”是对诚信的莫大讽刺
  7. 计算机音乐在生活中的应用论文,计算机音乐技术在音乐创作的应用
  8. excel 单元格与任意自定义内容拼接公式
  9. ASP.NET Web Forms 转换至MVC开发
  10. Android动态更换APP图标及名称