`
RednaxelaFX
  • 浏览: 3053390 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

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

    博客分类:
  • C#
阅读更多
C#的访问限制修饰符对应到Type的可见性属性有以下对应关系:

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

注意:这些属性之中总是有且只有一个属性为真。一个嵌套类的Type只会显示自身的可见性,其外围类的可见性需要通过Type.DeclaringType找到其外围类的Type来查询。
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 { }
}


运行结果:
引用
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 = False
  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 = False
  IsInterface = False
  IsEnum = False
  IsValueType = True
  IsPublic = False
  IsNotPublic = True
  IsNested = False
  IsNestedAssembly = False
  IsNestedFamily = False
  IsNestedFamilyAndAssembly = False
  IsNestedFamilyOrAssembly = False
  IsNestedPrivate = False
  IsNestedPublic = False

注意到嵌套类的全名中的'+',那是外围类的全名与嵌套类的类名连接的地方。

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

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

下面是用SVN trunk里的Mono.Cecil来做同样的测试:

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 { }
}


运行结果:
引用
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


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 = True
  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 = True
  IsInterface = False
  IsEnum = False
  IsValueType = True
  IsPublic = False
  IsNotPublic = True
  IsNested = False
  IsNestedAssembly = False
  IsNestedFamily = False
  IsNestedFamilyAndAssembly = False
  IsNestedFamilyOrAssembly = False
  IsNestedPrivate = False
  IsNestedPublic = False


注意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上关于Type.IsClass的文档:
MSDN 写道
Gets a value indicating whether the Type is a class; that is, not a value type or interface.

可以认为这是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()就行了?
分享到:
评论
2 楼 RednaxelaFX 2008-09-22  
cajon 写道

Microsoft.Cci也很好用。FxCop中包含它的Assembly。但是似乎没有开源。有Reflactor,开不开源,似乎不重要了。:)

没错,不只FxCop里有Common Compiler Infrastructure(CCI)的assembly,另外一个地方也有:Zonnon,而且两者用的assembly还不完全一样。而且CCI确实是不开源的,是个神秘的项目。在Project 7和7+以外的我们能了解到的关于CCI的信息太少了。FxCop的SDK也迟迟未公开呢。
1 楼 cajon 2008-09-22  
Microsoft.Cci也很好用。FxCop中包含它的Assembly。但是似乎没有开源。
有Reflactor,开不开源,似乎不重要了。:)

相关推荐

    Mono.Cecil.dll一个非常重要的插件

    Mono.Cecil.dll一个非常重要的插件

    稍微修改过的Mono.Cecil

    modified Mono.Cecil 博文链接:https://rednaxelafx.iteye.com/blog/245160

    Mono.Cecil.Samples:Mono.Cecil.Samples

    通过深入研究Mono.Cecil.Samples项目中的代码,开发者可以学到如何在实际项目中应用Mono.Cecil,提高代码的灵活性和可维护性。无论是进行自动化测试、代码分析、插件开发还是其他高级任务,Mono.Cecil都是一个不可或...

    unity可以用的System.Drawing.dll.zip

    为了解决这个问题,就需要单独下载适用于Unity的System.Drawing.dll版本,确保它与Unity的兼容性,并正确地将其导入到Unity工程中。 在Unity中使用System.Drawing.dll来播放GIF动画通常涉及以下步骤: 1. 首先,你...

    C# 静态注入实现AOP

    C#作为一种强大的.NET开发语言,虽然原生并不支持AOP,但可以通过一些第三方库来实现,如我们这里提到的`Mono.Cecil`。 `Mono.Cecil`是一个强大的.NET元数据操作库,它允许开发者在运行时动态地读取、修改并保存IL...

    unity-2020.3.14f1 mono-2.0-bdwgc

    5. **脚本改进**:C#支持可能得到增强,包括新的语言特性,如C# 8.0或更高版本的特性,如默认接口实现、非空引用类型等。 6. **动画系统**:Unity的Mecanim动画系统可能有新的功能和改进,例如更灵活的混合树、动画...

    System.Json.dll(附带LitJson.dll)动态链接库

    System.Json.dll和LitJson.dll是两个在开发过程中处理JSON数据时常见的库,尤其在Unity3d游戏引擎的C#环境中。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于网络通信和数据存储,因为它...

    C#连接Postgresql的两个dll文件:Npgsql.dll Mono.Security.dll

    总的来说,Npgsql.dll和Mono.Security.dll为C#开发者提供了一个方便的途径来与PostgreSQL数据库进行通信。理解这两个库的功能和使用方式,有助于在C#应用程序中实现高效、安全的数据库操作。随着技术的发展,Npgsql...

    C#连接PostgreSql需要的Npgsql.dll和Mono.Security.dll版本Npgsql-2.2.3-net35.zip

    string connectionString = "Server=127.0.0.1;Port=5432;Database=myDataBase;User Id=myUsername; Password=myPassword;...C#连接PostgreSql需要的Npgsql.dll和Mono.Security.dll,Npgsql-2.2.3-net35.zip

    centos6.x_mono_jexus_default.sh

    centos6.x_mono_jexus_default.sh

    NPgsql及Mono.Security各版本支持文件

    在.NET框架下,这些功能通常由System.Security命名空间提供,但Mono.Security为非Windows平台提供了等效的支持,特别是在使用Mono运行时的情况。 当NPgsql与Mono.Security结合使用时,它们可以为跨平台的.NET应用...

    C#连接PostgreSql需要的Npgsql.dll和Mono.Security.dll版本Npgsql-2.2.3-net40.zip

    string connectionString = "Server=127.0.0.1;Port=5432;Database=myDataBase;User Id=myUsername; Password=myPassword;...C#连接PostgreSql需要的Npgsql.dll和Mono.Security.dll,Npgsql-2.2.3-net40.zip

    MONO下访问eDirectory的动态链接库Mono.Security.dll

    在实际应用中,开发者可能需要结合其他MONO库,如`System.DirectoryServices.Protocols`(提供对LDAP操作的更底层访问)和`Mono.Posix`(帮助与非Windows系统进行交互),来构建完整的解决方案。此外,理解MONO的...

    基于.net framework 4.5 的postgresql 的连接api(Npgsql.dll,Mono.Security.dll)

    本篇将详细介绍如何使用Npgsql.dll和Mono.Security.dll这两个组件来建立和管理与PostgreSQL数据库的连接。 首先,让我们来了解Npgsql.dll。Npgsql是.NET社区维护的一个开源项目,它提供了全面的ADO.NET支持,包括...

    system.data的2.x版本和4.x版本

    此外,`System.Data.SqlClient`组件也得到了升级,增强了性能和兼容性,使得与SQL Server的交互更为高效。 在Unity中,由于其内建的 mono 运行时环境,早期版本可能仅支持.NET 2.0 Subset,这意味着只能使用`System...

    Mono.Data.Sqlite

    2. 兼容性:Mono.Data.Sqlite与.NET Framework的System.Data.SQLite库兼容,这使得代码可以在多种.NET环境中无缝迁移。 3. 平台独立:由于SQLite是跨平台的,所以Mono.Data.Sqlite也支持多种操作系统,如Windows、...

    System.Json.dll文件和LitJson.dll文件

    然而,由于Unity3D并不完全基于.NET Framework,而是使用了 Mono 版本的.NET,所以`System.Json.dll`在某些情况下可能不被完全支持或者效率不高。在Unity中直接使用这个库可能会遇到兼容性问题。 2. **LitJson.dll*...

    mono-6.12.0.107-x64-0.msi

    mono-6.12.0.107-x64-0.msi

    System.Drawing.dll

    支持 Unity 2019.3.3f1 以及之前的 system.Drawing.dll,很多人找不到,因为Unity 2019.3.3f1 版本 中 system.Drawing.dll,不在 unity的文件位置-&gt;Data-&gt;Mono-&gt;lib-&gt;mono-&gt;2.0-&gt;System.Drawing.dll 这个目录下面了...

    raspberry-sharp-io, 树莓派的. NET/Mono IO库.zip

    raspberry-sharp-io, 树莓派的. NET/Mono IO库 Raspberry# IO查看收费的 Raspberry# IO Wiki文档和示例。简介Raspberry# IO是 树莓派的. NET/Mono IO库。 这个项目是 Raspberry#社区的一个计划。当前版本是早期的pub

Global site tag (gtag.js) - Google Analytics