zoukankan      html  css  js  c++  java
  • NET 4,3,2,1其实什么也没有变

    NET 4,3,2,1其实什么也没有变

     

    最近,身边的不少程序员抱怨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变的只是实现这一目标的方式

     

  • 相关阅读:
    程序输出小学四则运算表达式,支持真分数四则运算
    自我介绍
    一维数组求最大子数组的和(首位相邻32位)
    一维数组子数组求最大和
    第三周进度条
    第三周总结PSP日志文件
    四则运算<3>单元测试
    四则运算<3>
    30道四则运算<2>单元测试
    构建之法阅读笔记02
  • 原文地址:https://www.cnblogs.com/foundation/p/1345438.html
Copyright © 2011-2022 走看看