当前位置: 移动技术网 > IT编程>开发语言>c# > 在Framework 4.0中:找出新增的方法与新增的类(二)

在Framework 4.0中:找出新增的方法与新增的类(二)

2019年07月18日  | 移动技术网IT编程  | 我要评论
问题描述:在framework 4.0中:找出新增的方法与新增的类(一)为什么动态加载程序集无法找出framework 4.0 和framwork2.0 新增的方法和类?&
问题描述:

为什么动态加载程序集无法找出framework 4.0 和framwork2.0 新增的方法和类?
 
因为控制台程序默认就添加了framework4.0的程序集,当你使用object,type,string这些类的时候就已经在使用已经加载的程序集了,而clr不会重复的去加载程序集??,这点记不清了。
所以v2assembly 和v4assembly都是framework4.0的assembly。

验证:
复制代码 代码如下:

static void main(string[] args)
{
    assembly assemblyv2 = assembly.loadfile(
                        @"c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll");
    assembly assemblyv4 = assembly.loadfile(
                        @"c:\windows\microsoft.net\framework\v4.0.30319\mscorlib.dll");
    console.writeline("v2的名称{0}\nv4的名称{1}", assemblyv2.fullname, assemblyv4.fullname);
    console.readline();
}

输出如下:

image 

因为mscorlib.dll 是在share domain中的程序集,所以在同一应用程序中无法加载两个不同的mscorlib.dll.所以考虑使用两个应用程序,一个framework 2.0,另一个framework 4.0。

于是可以换个思路:使用2.0framework来创建的程序来调用framework4.0wcf服务。

代码结构如下:

image

v4newlooker是基于framework 2.0winform程序

v4wcfservice是基于framework 4.0 wcf服务。

接口的定义如下:

复制代码 代码如下:

namespace v4wcfservice
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“iservice1”。
    [servicecontract]
    public interface iservice1
    {
        [operationcontract]
        list<typemembers> getnewtypemember(list<typemembers> lstoldtypes);
    }
    [datacontract]
    public class typemembers
    {
        [datamember]
        public string fullname { get; set; }
        [datamember]
        public list<string> membernames { get; set; }
    }
}

服务实现代码如下:
复制代码 代码如下:

namespace v4wcfservice
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“service1”。
    public class service1 : iservice1
    {
        public list<typemembers> getnewtypemember(list<typemembers> lstoldtypes)
        {
            list<typemembers> result = new list<typemembers>();
            assembly mscorlibassembly = typeof(object).assembly;
            type[] v4types = mscorlibassembly.gettypes();
            #region 所有更新的type
            foreach (typemembers v3type in lstoldtypes)
            {
                type v4type = v4types.firstordefault(t => t.fullname == v3type.fullname);

                if (v4type != null && !v4type.isenum)
                {
                    memberinfo[] v4mis = v4type.getmembers();
                    if (v4mis.length != v3type.membernames.count)
                    {
memberinfo[] v4newmis = v4mis.where(mi =>
    !v3type.membernames.contains(mi.name)).toarray();
                        result.add(new typemembers()
                        {
                            fullname = v4type.fullname,
                            membernames = v4newmis.select(mi => mi.name).tolist()
                        });
                    }
                }
            }
            #endregion
            #region 所有新增的type
            list<string> v3typefullname = lstoldtypes.select(tm => tm.fullname).tolist();
type[] v4newtypes = v4types.where(t => !v3typefullname.contains(t.fullname) &&
!t.isenum).toarray();
            foreach (type v4newtype in v4newtypes)
            {
                result.add(new typemembers()
                {
                    fullname = v4newtype.fullname,
                    membernames = v4newtype.getmembers().select(mi => mi.name).tolist()
                });
            }
            #endregion
            return result.orderby(tm=>tm.fullname).tolist();
        }
    }
}

服务的实现和第一个反射的版本差不多。

web.config文件绑定代码如下:
复制代码 代码如下:

<system.servicemodel>
    <bindings>
      <wshttpbinding>
        <binding name="newbinding0" maxreceivedmessagesize="65536000" />
      </wshttpbinding>
      <mexhttpbinding>
        <binding name="newbinding1" />
      </mexhttpbinding>
    </bindings>
    <services>
      <service behaviorconfiguration="v4wcfservice.service1behavior"
        name="v4wcfservice.service1">
        <endpoint address="" binding="wshttpbinding" bindingconfiguration="newbinding0"
          contract="v4wcfservice.iservice1">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexhttpbinding" bindingconfiguration="newbinding1"
          contract="imetadataexchange" />
      </service>
    </services>
    <behaviors>
      <servicebehaviors>
        <behavior name="v4wcfservice.service1behavior">
          <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
          <servicemetadata httpgetenabled="true"/>
          <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
          <servicedebug includeexceptiondetailinfaults="false"/>
        </behavior>
      </servicebehaviors>
    </behaviors>
  </system.servicemodel>

因为默认的maxreceivedmessagesize 65536,所以在后面增加了两个0, 否则会抛出经典的超出范围的异常。

winform程序界面如下:

image 

后台代码如下:

复制代码 代码如下:

namespace v4newlooker
{
    public partial class form1 : form
    {
        public form1()
        {
            initializecomponent();
        }
        private list<typemembers> newtypemembers { get; set; }
        private void btnsearch_click(object sender, eventargs e)
        {
            assembly mscorlibassembly = typeof(object).assembly;
            list<typemembers> v3typemembers = new list<typemembers>();
            foreach (type v4newtype in mscorlibassembly.gettypes())
            {
                list<string> membernames = new list<string>();
                memberinfo[] mis = v4newtype.getmembers();
                foreach (memberinfo mi in mis)
                {
                    membernames.add(mi.name);
                }
                v3typemembers.add(new typemembers()
                {
                    fullname = v4newtype.fullname,
                    membernames = membernames
                });
            }
            using (service1client client = new service1client())
            {
                newtypemembers = client.getnewtypemember(v3typemembers);
            }
            list<string> typenames=new list<string>();
            foreach (typemembers tm in newtypemembers)
            {
                typenames.add(tm.fullname);
            }
            lstbox_types.datasource = typenames;
        }
        private void lstbox_types_selectedindexchanged(object sender, eventargs e)
        {
            string fullname = lstbox_types.selecteditem.tostring();
            foreach (typemembers tm in newtypemembers)
            {
                if (tm.fullname == fullname)
                {
                    lstbox_members.datasource = tm.membernames;
                    break;
                }
            }
        }
    }
}

搜索按钮的功能就是把当前framework 2.0的所有的type,所有的type中的memberinfo封装成请求,然后调用wcf服务。服务就会根据传递过来的typememberinfo来输出新增的方法和类。

运行效果如下:

image 

可以看到4.0的file类增加了readlines.appendalllines方法。上面看到两个readlines是因为readlines方法由两个重载。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网