zoukankan      html  css  js  c++  java
  • [转].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变的只是实现这一目标的方式

  • 相关阅读:
    改造vant日期选择
    css3元素垂直居中
    npm综合
    (转)网页加水印方法
    Mac下IDEA自带MAVEN插件的全局环境配置
    隐藏注册控件窗口
    High performance optimization and acceleration for randomWalk, deepwalk, node2vec (Python)
    How to add conda env into jupyter notebook installed by pip
    The Power of WordNet and How to Use It in Python
    背单词app测评,2018年
  • 原文地址:https://www.cnblogs.com/killkill/p/1372242.html
Copyright © 2011-2022 走看看