C# Type 序列化问题

原创 2011年01月21日 10:56:00

序列化时使用:type.AssemblyQualifiedName 将Type转换成字符串保存,

 

 

反序列化时使用如下方法:

 

Type.GetType(AN,T) actually translates to Assembly.Load(AN).GetType(T). This actually can be the cause of many confusions. Often programmers end up in a situation where they have explicitly loaded the assembly, but Type.GetType is not able to find the type from the assembly they just loaded.

 

Let us look into the sample below. Let us do a Type.GetType for Foo and provide the path to the location of Foo in the config file as mentioned below.

 

Copy the source below to TypeSample.cs and the config to TypeSample.exe.config

 

using System;

using System.Reflection;

class DomSample {

    public static void Main(){

        try {

            Type ty1 = Type.GetType("Foo, Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1faea1974f697f94");

            if (ty1 != null) {

                Console.WriteLine("V1 Type = {0}", ty1.Assembly.FullName.ToString());

            }

            else {

                Console.WriteLine("Unable to find type ...");

            }

        }

        catch (Exception e) {

            Console.WriteLine(e.ToString());

        }

    }

}

 

<configuration>

   <runtime>

      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

         <probing privatePath="v1" />

      </assemblyBinding>

   </runtime>

</configuration>

 

 

Make sure that you create a path v1 under APPBASE and create a Foo.cs which is compiled and signed to Foo.dll. Copy the following source to Foo.cs and comple it to Foo.dll and sign it with the key (see my article on signinig)

 

using System;

using System.Reflection;

[assembly: System.Reflection.AssemblyVersion("1.0.0.0")]

public class Foo {

    public void Bar() {

        Console.WriteLine("Version = {0}", (Assembly.GetExecutingAssembly()).ToString());

    }

}

 

 

If you run TypeSample.exe you will get the following output

V1 Type = Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1faea1974f697f94

 

If you run the sample under ntsd you will notice that Foo.dll is loaded from directory v1 in the default AppDomain

 

 

Opened log file 'ntsd.log'

0:000> !dumpdomain

--------------------------------------

System Domain: 7a390b60

LowFrequencyHeap: 7a390b84

HighFrequencyHeap: 7a390be0

StubHeap: 7a390c3c

Stage: OPEN

Name: None

--------------------------------------

Shared Domain: 7a391138

LowFrequencyHeap: 7a39115c

HighFrequencyHeap: 7a3911b8

StubHeap: 7a391214

Stage: OPEN

Name: None

Assembly: 001e8828

--------------------------------------

Domain 1: 001b0890

LowFrequencyHeap: 001b08b4

HighFrequencyHeap: 001b0910

StubHeap: 001b096c

Stage: OPEN

SecurityDescriptor: 001b1a98

Name: DomSample.exe

Assembly: 001e8828 [C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll]

ClassLoader: 001e88c0

SecurityDescriptor: 001e8738

  Module Name

790c2000 C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll

 

Assembly: 001f95e0 [c:/blog/May2007/DomSample.exe]

ClassLoader: 001f9678

SecurityDescriptor: 001f94e0

  Module Name

00712c24 c:/blog/May2007/DomSample.exe

 

Assembly: 00208128 [c:/blog/May2007/v1/Foo.dll]

ClassLoader: 00208398

SecurityDescriptor: 00208298

  Module Name

007130d8 c:/blog/May2007/v1/Foo.dll

 

 

Now let us modify the code above to use LoadFrom and then try the Type.GetType.

 

Copy the code below to TypeSampleLoadFrom.cs and compile it to TypeSampleLoadFrom.exe. Let us not provide a config file this time such Type.GetType cannot find the assembly Foo when it tries to load it.

 

using System;

using System.Reflection;

class DomSample {

    public static void Main() {

        try {

            Assembly.LoadFrom("c://Blog//May2007//v2//Foo.dll");

            Type ty1 = Type.GetType("Foo, Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1faea1974f697f94");

            if(ty1 != null) {

                Console.WriteLine("V1 Type = {0}",ty1.Assembly.FullName.ToString());

            }

            else {

                Console.WriteLine("Unable to find type ...");

            }

        }

        catch(Exception e) {

            Console.WriteLine(e.ToString());

        }

    }

}

 

 

The above program yields the result "Unable to find type ...". If you watch the program under ntsd you will notice that Foo.dll is loaded from the LoadFrom, but the Type.GetType was not able to use the already loaded Foo.dll or find Foo.dll to load it to retreive the type information

 

 

0:001> !dumpdomain

--------------------------------------

System Domain: 7a390b60

LowFrequencyHeap: 7a390b84

HighFrequencyHeap: 7a390be0

StubHeap: 7a390c3c

Stage: OPEN

Name: None

--------------------------------------

Shared Domain: 7a391138

LowFrequencyHeap: 7a39115c

HighFrequencyHeap: 7a3911b8

StubHeap: 7a391214

Stage: OPEN

Name: None

Assembly: 002e86e8

--------------------------------------

Domain 1: 002b08c8

LowFrequencyHeap: 002b08ec

HighFrequencyHeap: 002b0948

StubHeap: 002b09a4

Stage: OPEN

Name: DomSample1.exe

Assembly: 002e86e8 [C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll]

ClassLoader: 002e8780

SecurityDescriptor: 002f4ef8

  Module Name

790c2000 C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll

 

Assembly: 002fa790 [c:/blog/May2007/DomSample1.exe]

ClassLoader: 002fa828

SecurityDescriptor: 002fa690

  Module Name

00102c24 c:/blog/May2007/DomSample1.exe

 

Assembly: 00302bc0 [c:/Blog/May2007/v2/Foo.dll]

ClassLoader: 003072b0

SecurityDescriptor: 00306b88

  Module Name

00103120 c:/Blog/May2007/v2/Foo.dll

 

 

Let us modify the above sample and add a config TypeSampleLoadFrom.exe.config as follows

 

<configuration>

   <runtime>

      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

         <probing privatePath="v1" />

      </assemblyBinding>

   </runtime>

</configuration>

 

You will get the output  V1 Type = Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1faea1974f697f94.

 

If you run the program under the debugger you will find that there are two Foo.dll loaded in the default AppDomain one loaded from the LoadFrom context and the other load by Type.GetType in the other context. I had specifically placed the same Foo.dll in different locations to make this happen. The Foo.dll loaded by Type.GetType was loaded from v1 directory and the Foo.dll loaded from the LoadFrom context was loaded from v2 directory. If you had both point to the same location, you will however see only one copy of the dll.

 

0:000> !dumpdomain

--------------------------------------

System Domain: 7a390b60

LowFrequencyHeap: 7a390b84

HighFrequencyHeap: 7a390be0

StubHeap: 7a390c3c

Stage: OPEN

Name: None

--------------------------------------

Shared Domain: 7a391138

LowFrequencyHeap: 7a39115c

HighFrequencyHeap: 7a3911b8

StubHeap: 7a391214

Stage: OPEN

Name: None

Assembly: 003386f8

--------------------------------------

Domain 1: 003008a0

LowFrequencyHeap: 003008c4

HighFrequencyHeap: 00300920

StubHeap: 0030097c

Stage: OPEN

SecurityDescriptor: 00301aa8

Name: DomSample1.exe

Assembly: 003386f8 [C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll]

ClassLoader: 00338790

SecurityDescriptor: 00344ed0

  Module Name

790c2000 C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll

 

Assembly: 0034a7c8 [c:/blog/May2007/DomSample1.exe]

ClassLoader: 0034a860

SecurityDescriptor: 0034a6c8

  Module Name

002d2c24 c:/blog/May2007/DomSample1.exe

 

Assembly: 00365b00 [c:/Blog/May2007/v2/Foo.dll]

ClassLoader: 00365998

SecurityDescriptor: 00358038

  Module Name

002d3120 c:/Blog/May2007/v2/Foo.dll

 

Assembly: 00366bd0 [c:/blog/May2007/v1/Foo.dll]

ClassLoader: 00366a58

SecurityDescriptor: 00365c48

  Module Name

002d3548 c:/blog/May2007/v1/Foo.dll

 

参考文章:

http://blogs.msdn.com/b/thottams/archive/2007/05/11/load-contexts-and-type-gettype.aspx

 

http://stackoverflow.com/questions/629666/c-type-gettype-called-from-a-dll-on-exe-type-string


本文来自SunShine,转载请标明出处:http://do.jhost.cn/sunshine/ReadNews?action=read&id=244

C#中类型Type的GetMethod方法

C#中类型Type有个GetMethod方法,调用该方法可获取指定方法名的方法信息实例。 使用时,其参数一般为2个,一个是方法名称字符串(可设置条件忽略大小写),另外一个参数为搜索方法的条件枚举。 ...
  • fuyifang
  • fuyifang
  • 2016年11月04日 16:56
  • 1843

关于C#的Type.GetType血泪史

关于C#的Type.GetType血泪史
  • longchuanzouxuexiang
  • longchuanzouxuexiang
  • 2015年06月10日 13:40
  • 1549

c#反射Type类型的一些方法介绍

=====TestLib.dll文件内容======== using System; using System.Collections.Generic; using System.Linq; ...
  • limlimlim
  • limlimlim
  • 2013年02月22日 16:12
  • 7419

C# Type传参转换成泛型T

示例代码 public class Test{ public void Export() { } public void ExportByClassN...
  • fgfg12345
  • fgfg12345
  • 2015年04月17日 16:28
  • 1323

c# System.Type.GetType()方法

想用System.Type.GetType()方法获取不在同一个程序集中定义指定类型:/* 注意: * 此段代码属于:程序集lu.Data,命名空间lu.Data与要加载类定义于不同的程序集项目中,但...
  • lulu_jiang
  • lulu_jiang
  • 2011年06月05日 19:25
  • 8013

【C#反射-Type类】

一.反射的作用: 查看和遍历类型和类型的元数据;动态创建类型实例,动态的调用所创建的实例方法和字段,属性,迟绑定方法和属性。 二.获取Type对象实例: 反射的核心类-Type,封装了关于类...
  • heyangyi_19940703
  • heyangyi_19940703
  • 2016年05月07日 16:20
  • 934

C# Json序列化工具--Newtonsoft.Json简介和使用

Newtonsoft.Json,是.Net中开源的Json序列化和反序列化工具,官方地址:http://www.newtonsoft.com/json。 功能比较多,效率比较高,官方给出对比数据 50...
  • u011127019
  • u011127019
  • 2016年06月18日 18:03
  • 15019

C#中的Type

Type 类 表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。 Type 初始化 Type ...
  • zy332719794
  • zy332719794
  • 2012年12月19日 09:25
  • 937

23

问题        在输入数据无序的情况下,建立一个数据值为整型的递增有序的顺序存储线性表L,且要求当输入相同数据值时,线性表中不能存在数据值相同的数据元素 分析       和22思路一样  ...
  • u013180963
  • u013180963
  • 2016年10月02日 23:20
  • 107

23.获取文件的MIMEType

第一种- (NSString *)MIMEType { if (![[NSFileManager defaultManager] fileExistsAtPath:self]) { r...
  • shn19891109
  • shn19891109
  • 2016年03月20日 10:02
  • 130
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# Type 序列化问题
举报原因:
原因补充:

(最多只允许输入30个字)