类型的可见性,System.Reflection与Mono.Cecil的差异

C#的访问限制修饰符对应到Type的可见性属性有以下对应关系:

顶层类:
public -> IsPublic
internal -> IsNotPublic
(默认)-> internal -> IsNotPublic
嵌套类:
public -> IsNestedPublic
protected -> IsNestedFamily
protected internal -> IsNestedFamilyOrAssembly
private -> IsNestedPrivate
(默认)-> private -> IsNestedPrivate

[color=blue]注意:这些属性之中总是有且只有一个属性为真。一个嵌套类的Type只会显示自身的可见性,其外围类的可见性需要通过Type.DeclaringType找到其外围类的Type来查询。[/color]
C#无法表示IsFamANDAssem可见性的类型。

用一段代码通过System.Reflection来测试一下上述对应关系:

using System;
using System.Reflection;

namespace TestReflection {
static class Program {
static void Main( string[ ] args ) {
var asm = Assembly.GetExecutingAssembly( );
foreach ( var type in asm.GetTypes( ) ) {
PrintTypeInfo( type );
}
}

static void PrintTypeInfo( Type type ) {
Console.WriteLine( "Type: {0}", type.ToString( ) );
Console.WriteLine( " Name: {0}", type.Name );
Console.WriteLine( " FullName: {0}", type.FullName ?? "null" );

// type of type
Console.WriteLine( " IsClass = {0}", type.IsClass );
Console.WriteLine( " IsInterface = {0}", type.IsInterface );
Console.WriteLine( " IsEnum = {0}", type.IsEnum );
Console.WriteLine( " IsValueType = {0}", type.IsValueType );

// access modifiers
Console.WriteLine( " IsPublic = {0}", type.IsPublic );
Console.WriteLine( " IsNotPublic = {0}", type.IsNotPublic );
Console.WriteLine( " IsNested = {0}", type.IsNested );
Console.WriteLine( " IsNestedAssembly = {0}", type.IsNestedAssembly );
Console.WriteLine( " IsNestedFamily = {0}", type.IsNestedFamily );
Console.WriteLine( " IsNestedFamilyAndAssembly = {0}", type.IsNestedFamANDAssem );
Console.WriteLine( " IsNestedFamilyOrAssembly = {0}", type.IsNestedFamORAssem );
Console.WriteLine( " IsNestedPrivate = {0}", type.IsNestedPrivate );
Console.WriteLine( " IsNestedPublic = {0}", type.IsNestedPublic );

Console.WriteLine( );
}
}

public class PublicClass {
public class PublicInnerPublicClass { }
internal class InternalInnerPublicClass { }
protected class ProtectedInnerPublicClass { }
protected internal class ProtectedInternalInnerPublicClass { }
private class PrivateInnerPublicClass { }
class DefaultInnerPublicClass { }
}

/*internal*/
class InternalClass {
public class PublicInnerInternalClass { }
internal class InternalInnerInternalClass { }
protected class ProtectedInnerInternalClass { }
protected internal class ProtectedInternalInnerInternalClass { }
private class PrivateInnerInternalClass { }
class DefaultInnerInternalClass { }
}

enum InternalEnum { A }
struct InternalStruct { }
}


运行结果:
[quote]Type: TestReflection.Program
Name: Program
FullName: TestReflection.Program
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.PublicClass
Name: PublicClass
FullName: TestReflection.PublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = True
IsNotPublic = False
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.PublicClass+PublicInnerPublicClass
Name: PublicInnerPublicClass
FullName: TestReflection.PublicClass+PublicInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = True

Type: TestReflection.PublicClass+InternalInnerPublicClass
Name: InternalInnerPublicClass
FullName: TestReflection.PublicClass+InternalInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = True
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.PublicClass+ProtectedInnerPublicClass
Name: ProtectedInnerPublicClass
FullName: TestReflection.PublicClass+ProtectedInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = True
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.PublicClass+ProtectedInternalInnerPublicClass
Name: ProtectedInternalInnerPublicClass
FullName: TestReflection.PublicClass+ProtectedInternalInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = True
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.PublicClass+PrivateInnerPublicClass
Name: PrivateInnerPublicClass
FullName: TestReflection.PublicClass+PrivateInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = True
IsNestedPublic = False

Type: TestReflection.PublicClass+DefaultInnerPublicClass
Name: DefaultInnerPublicClass
FullName: TestReflection.PublicClass+DefaultInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = True
IsNestedPublic = False

Type: TestReflection.InternalClass
Name: InternalClass
FullName: TestReflection.InternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.InternalClass+PublicInnerInternalClass
Name: PublicInnerInternalClass
FullName: TestReflection.InternalClass+PublicInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = True

Type: TestReflection.InternalClass+InternalInnerInternalClass
Name: InternalInnerInternalClass
FullName: TestReflection.InternalClass+InternalInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = True
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.InternalClass+ProtectedInnerInternalClass
Name: ProtectedInnerInternalClass
FullName: TestReflection.InternalClass+ProtectedInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = True
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.InternalClass+ProtectedInternalInnerInternalClass
Name: ProtectedInternalInnerInternalClass
FullName: TestReflection.InternalClass+ProtectedInternalInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = True
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.InternalClass+PrivateInnerInternalClass
Name: PrivateInnerInternalClass
FullName: TestReflection.InternalClass+PrivateInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = True
IsNestedPublic = False

Type: TestReflection.InternalClass+DefaultInnerInternalClass
Name: DefaultInnerInternalClass
FullName: TestReflection.InternalClass+DefaultInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = True
IsNestedPublic = False

Type: TestReflection.InternalEnum
Name: InternalEnum
FullName: TestReflection.InternalEnum
IsClass = [color=green][b]False[/b][/color]
IsInterface = False
IsEnum = True
IsValueType = True
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestReflection.InternalStruct
Name: InternalStruct
FullName: TestReflection.InternalStruct
IsClass = [color=green][b]False[/b][/color]
IsInterface = False
IsEnum = False
IsValueType = True
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False[/quote]
注意到嵌套类的全名中的'+',那是外围类的全名与嵌套类的类名连接的地方。

===========================================================================

用System.Reflection来加载assembly有一个缺点,那就是加载了的assembly在程序结束前无法卸载,会一直占用内存。为了绕开这个问题,可以用[url=http://www.mono-project.com/Cecil]Mono.Cecil[/url]来加载assembly并获取相关类型信息。

下面是用[url=svn://anonsvn.mono-project.com/source/trunk/mcs/class/Mono.Cecil]SVN trunk里的Mono.Cecil[/url]来做同样的测试:

using System;
using System.Reflection;
using Mono.Cecil;

namespace TestCecil {
static class Program {
static void Main( string[ ] args ) {
var path = Assembly.GetExecutingAssembly( ).Location;
AssemblyDefinition asm = AssemblyFactory.GetAssembly( path );
ModuleDefinition module = asm.MainModule;
foreach ( TypeDefinition type in module.Types ) {
PrintTypeInfo( type );
}
}

static void PrintTypeInfo( TypeDefinition type ) {
Console.WriteLine( "Type: {0}", type.ToString( ) );
Console.WriteLine( " Name: {0}", type.Name );
Console.WriteLine( " FullName: {0}", type.FullName ?? "null" );

// type of type
Console.WriteLine( " IsClass = {0}", type.IsClass );
Console.WriteLine( " IsInterface = {0}", type.IsInterface );
Console.WriteLine( " IsEnum = {0}", type.IsEnum );
Console.WriteLine( " IsValueType = {0}", type.IsValueType );

// access modifiers
Console.WriteLine( " IsPublic = {0}", type.IsPublic );
Console.WriteLine( " IsNotPublic = {0}", type.IsNotPublic );
Console.WriteLine( " IsNested = {0}", type.IsNested );
Console.WriteLine( " IsNestedAssembly = {0}", type.IsNestedAssembly );
Console.WriteLine( " IsNestedFamily = {0}", type.IsNestedFamily );
Console.WriteLine( " IsNestedFamilyAndAssembly = {0}", type.IsNestedFamilyAndAssembly );
Console.WriteLine( " IsNestedFamilyOrAssembly = {0}", type.IsNestedFamilyOrAssembly );
Console.WriteLine( " IsNestedPrivate = {0}", type.IsNestedPrivate );
Console.WriteLine( " IsNestedPublic = {0}", type.IsNestedPublic );

Console.WriteLine( );
}
}

public class PublicClass {
public class PublicInnerPublicClass { }
internal class InternalInnerPublicClass { }
protected class ProtectedInnerPublicClass { }
protected internal class ProtectedInternalInnerPublicClass { }
private class PrivateInnerPublicClass { }
class DefaultInnerPublicClass { }
}

/*internal*/
class InternalClass {
public class PublicInnerInternalClass { }
internal class InternalInnerInternalClass { }
protected class ProtectedInnerInternalClass { }
protected internal class ProtectedInternalInnerInternalClass { }
private class PrivateInnerInternalClass { }
class DefaultInnerInternalClass { }
}

enum InternalEnum { A }
struct InternalStruct { }
}


运行结果:
[quote][color=blue]Type: <Module>
Name: <Module>
FullName: <Module>
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False[/color]

Type: TestCecil.Program
Name: Program
FullName: TestCecil.Program
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.PublicClass
Name: PublicClass
FullName: TestCecil.PublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = True
IsNotPublic = False
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.PublicClass/PublicInnerPublicClass
Name: PublicInnerPublicClass
FullName: TestCecil.PublicClass/PublicInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = True

Type: TestCecil.PublicClass/InternalInnerPublicClass
Name: InternalInnerPublicClass
FullName: TestCecil.PublicClass/InternalInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = True
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.PublicClass/ProtectedInnerPublicClass
Name: ProtectedInnerPublicClass
FullName: TestCecil.PublicClass/ProtectedInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = True
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.PublicClass/ProtectedInternalInnerPublicClass
Name: ProtectedInternalInnerPublicClass
FullName: TestCecil.PublicClass/ProtectedInternalInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = True
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.PublicClass/PrivateInnerPublicClass
Name: PrivateInnerPublicClass
FullName: TestCecil.PublicClass/PrivateInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = True
IsNestedPublic = False

Type: TestCecil.PublicClass/DefaultInnerPublicClass
Name: DefaultInnerPublicClass
FullName: TestCecil.PublicClass/DefaultInnerPublicClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = True
IsNestedPublic = False

Type: TestCecil.InternalClass
Name: InternalClass
FullName: TestCecil.InternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.InternalClass/PublicInnerInternalClass
Name: PublicInnerInternalClass
FullName: TestCecil.InternalClass/PublicInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = True

Type: TestCecil.InternalClass/InternalInnerInternalClass
Name: InternalInnerInternalClass
FullName: TestCecil.InternalClass/InternalInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = True
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.InternalClass/ProtectedInnerInternalClass
Name: ProtectedInnerInternalClass
FullName: TestCecil.InternalClass/ProtectedInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = True
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.InternalClass/ProtectedInternalInnerInternalClass
Name: ProtectedInternalInnerInternalClass
FullName: TestCecil.InternalClass/ProtectedInternalInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = True
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.InternalClass/PrivateInnerInternalClass
Name: PrivateInnerInternalClass
FullName: TestCecil.InternalClass/PrivateInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = True
IsNestedPublic = False

Type: TestCecil.InternalClass/DefaultInnerInternalClass
Name: DefaultInnerInternalClass
FullName: TestCecil.InternalClass/DefaultInnerInternalClass
IsClass = True
IsInterface = False
IsEnum = False
IsValueType = False
IsPublic = False
IsNotPublic = False
IsNested = True
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = True
IsNestedPublic = False

Type: TestCecil.InternalEnum
Name: InternalEnum
FullName: TestCecil.InternalEnum
IsClass = [color=red][b]True[/b][/color]
IsInterface = False
IsEnum = True
IsValueType = True
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False

Type: TestCecil.InternalStruct
Name: InternalStruct
FullName: TestCecil.InternalStruct
IsClass = [color=red][b]True[/b][/color]
IsInterface = False
IsEnum = False
IsValueType = True
IsPublic = False
IsNotPublic = True
IsNested = False
IsNestedAssembly = False
IsNestedFamily = False
IsNestedFamilyAndAssembly = False
IsNestedFamilyOrAssembly = False
IsNestedPrivate = False
IsNestedPublic = False[/quote]

注意Mono.Cecil在这个测试里与System.Reflection的差异:
1、使用Mono.Cecil的ModuleDefinition.Types能得到<Module>类的信息,而直接用System.Reflection的Assembly.GetTypes()不会得到这个类的信息;
2、System.Reflection使用加号('+')来连接外围类与内部类的名字,而Mono.Cecil使用斜杠('/');
3、System.Reflection的Type.IsClass对值类型返回false,而Mono.Cecil的TypeDefinition.IsClass对值类型返回true。(注意运行结果中红色的字)
MSDN上关于[url=http://msdn.microsoft.com/en-us/library/system.type.isclass.aspx]Type.IsClass[/url]的文档:
[quote="MSDN"]Gets a value indicating whether the Type is a class; that is, not a value type or interface.[/quote]
可以认为这是Mono.Cecil的一个bug。前面提到,我用的是现在SVN trunk里的版本,也就是说这个问题可能之前一直都有。查看相关的实现:

Mono.Cecil/TypeAttributes.cs
[Flags]
public enum TypeAttributes : uint {
// ...

// Class semantics attributes
ClassSemanticMask = 0x00000020, // Use this mask to retrieve class semantics information
Class = 0x00000000, // Type is a class
Interface = 0x00000020, // Type is an interface

// ...
}


Mono.Cecil/TypeDefinition.cs
#region TypeAttributes

// ...

public bool IsClass {
get { return (m_attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Class; }
set {
if (value) {
m_attributes &= ~TypeAttributes.ClassSemanticMask;
m_attributes |= TypeAttributes.Class;
} else
m_attributes &= ~(TypeAttributes.ClassSemanticMask & TypeAttributes.Class);
}
}

// ...

#endregion

public bool IsEnum {
get { return m_baseType != null && m_baseType.FullName == Constants.Enum; }
}

public override bool IsValueType {
get {
return m_baseType != null && (
this.IsEnum || (m_baseType.FullName == Constants.ValueType && this.FullName != Constants.Enum));
}
}


要修正这个问题很简单,只要在TypeDefinition.IsClass的get方法的返回语句最后加上&& !this.IsValueType就行,变成这样:
public bool IsClass {
get { return (m_attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Class && !this.IsValueType; }
// ...
}


修改后这个差异就消失了。

===========================================================================

另外也看到Mono.Cecil中的一些细微的可改进的地方(?)
ImageReader.cs
line 69: FileInfo fi = new FileInfo (file);
line 70: if (!File.Exists (fi.FullName))
或许在第70行用fi.Exists()就行了?
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Failed to find entry-points: System.Exception: Unexpected exception while collecting types in assembly `Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null` ---> Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'GameFramework, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) [0x00105] in <ebb9e4250ed24cbfa42055e3532ef311>:0 at zzzUnity.Burst.CodeGen.AssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name) [0x00039] in <a2dd15248a25411e914af2a2c82fb63f>:0 at Burst.Compiler.IL.AssemblyLoader.Resolve (Mono.Cecil.AssemblyNameReference name) [0x00079] in <a2dd15248a25411e914af2a2c82fb63f>:0 at Mono.Cecil.MetadataResolver.Resolve (Mono.Cecil.TypeReference type) [0x00038] in <ebb9e4250ed24cbfa42055e3532ef311>:0 at Mono.Cecil.ModuleDefinition.Resolve (Mono.Cecil.TypeReference type) [0x00006] in <ebb9e4250ed24cbfa42055e3532ef311>:0 at Mono.Cecil.TypeReference.Resolve () [0x00006] in <ebb9e4250ed24cbfa42055e3532ef311>:0 at Burst.Compiler.IL.Server.EntryPointMethodFinder.CollectGenericTypeInstances (Mono.Cecil.TypeReference type, System.Collections.Generic.List`1[T] types, System.Collections.Generic.HashSet`1[T] visited) [0x0002f] in <a2dd15248a25411e914af2a2c82fb63f>:0 at Burst.Compiler.IL.Server.EntryPointMethodFinder.CollectGenericTypeInstances (Mono.Cecil.AssemblyDefinition assembly, System.Collections.Generic.List`1[T] types, System.Collections.Generic.HashSet`1[T] visited) [0x00057] in <a2dd15248a25411e914af2a2c82fb63f>:0 at Burst.Compiler.IL.Server.EntryPointMethodFinder.FindEntryPoints (System.String[] rootAssemblyNames, Burst.Compiler.IL.Hashing.CacheRuntime.HashCacheAssemblyStore assemblyStore, Burst.Compiler.IL.AssemblyLoader assemblyLoader, Burst.Compiler.IL.NativeCompilerOptions options, Burst.Compiler.IL.Server.ProfileDelegate profileCallback, System.Boolean includeRootAssemblyReferences, System.Boolean splitTargets, Burst.Compiler.IL.Helpers.DebugLogWriter debugWriter) [0x0019d] in <a2dd15248a25411e914af2a2c82fb63f>:0 --- End of inner exception stack trace --- at Burst.Compiler.IL.Server.EntryPointMethodFinder.FindEntryPoints (System.String[] rootAssemblyNames, Burst.Compiler.IL.Hashing.CacheRuntime.HashCacheAssemblyStore assemblyStore, Burst.Compiler.IL.AssemblyLoader assemblyLoader, Burst.Compiler.IL.NativeCompilerOptions options, Burst.Compiler.IL.Server.ProfileDelegate profileCallback, System.Boolean includeRootAssemblyReferences, System.Boolean splitTargets, Burst.Compiler.IL.Helpers.DebugLogWriter debugWriter) [0x001d9] in <a2dd15248a25411e914af2a2c82fb63f>:0 at Burst.Compiler.IL.Server.FindMethodsJob.Execute (Burst.Compiler.IL.Server.CompilerServerJobExecutionContext context) [0x00133] in <a2dd15248a25411e914af2a2c82fb63f>:0
最新发布
05-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值