【问题标题】:How to use reflection to determine if a class is internal?如何使用反射来确定一个类是否是内部的?
【发布时间】:2011-02-11 16:00:30
【问题描述】:

正如标题所说,如何使用反射来检查类定义是否定义为内部? "typeof(...)" 返回如下所示的某些属性,但不返回一个类是否定义为内部的。在 Google 上查看,但我只能找到很多关于使用反射运行内部或受保护方法的文章。我对这个案例感兴趣的不是方法,而是类定义。

var type = typeof(Customer);
Assert.IsTrue(type.IsClass);
Assert.That(type.IsAbstract, Is.EqualTo(isAbstract));
Assert.That(type.IsPublic, Is.EqualTo(isPublic));
Assert.That(type.IsPublic, Is.EqualTo(isPublic));
Assert.That(type.IsSealed, Is.EqualTo(isSealed));
Assert.That(type.IsSerializable, Is.EqualTo(isSerializable));

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    这是一个经典问题。来自MSDN

    C# 关键字 protectedinternal 在 IL 中没有意义,也没有在反射 API 中使用。 IL 中对应的术语是FamilyAssembly。要使用反射识别internal 方法,请使用IsAssembly 属性。要识别protected internal 方法,请使用IsFamilyOrAssembly

    Reflection 不会在 Type 上暴露路径,检查它是 internalprotected 还是 protected internal

    【讨论】:

    • 我不确定 MSDN 文档是否准确,但也许我错了。例如,我知道Tuple<> 实现了internal interface ITuple。此界面上的Type 具有用于上述标志的false。我自己的内部类的测试表现相同。
    • 此外,Nested 对我来说读作class A { class B { } },其中B 嵌套在A 中。文档中特别提到的属性IsAssemblyIsFamily 并未在Type 对象上公开提供。
    • 一个小修正:C# protected internal 对应于 CLR FamORAssem(即对同一程序集或派生类型中的任何内容可见)。 FamANDAssem 没有对应的 C# 等效项(除了我的梦想)。
    • 主要感谢@Jason 的快速而详细的回答。感谢其他所有人提供更多详细信息。在获得答案方面,Stack Overflow 确实是狗!
    • @AnthonyPegram 对于非嵌套类型,即作为命名空间的直接成员且不包含在外部类/结构中的类型,可能有两个级别。在反射中,它们对应于 IsPublicIsNotPublic 属性。这些属性为 all 嵌套类型返回 false。对于嵌套类型,请使用IsNestedFamOrAssemIsNestedPrivate 等属性(均以IsNested... 开头)。
    【解决方案2】:

    IsVisible 方法是否为您提供了您正在寻找的价值?

    【讨论】:

    • IsVisible 无疑是一种确定界面内部可见性的有效方法。
    【解决方案3】:

    这里有一些函数可以保证提供正确的类型可见性(可能是一个矫枉过正的实现):

    bool isPublic(Type t) {
        return
            t.IsVisible
            && t.IsPublic
            && !t.IsNotPublic
            && !t.IsNested
            && !t.IsNestedPublic
            && !t.IsNestedFamily
            && !t.IsNestedPrivate
            && !t.IsNestedAssembly
            && !t.IsNestedFamORAssem
            && !t.IsNestedFamANDAssem;
    }
    
    bool isInternal(Type t) {
        return
            !t.IsVisible
            && !t.IsPublic
            && t.IsNotPublic
            && !t.IsNested
            && !t.IsNestedPublic
            && !t.IsNestedFamily
            && !t.IsNestedPrivate
            && !t.IsNestedAssembly
            && !t.IsNestedFamORAssem
            && !t.IsNestedFamANDAssem;
    }
    
    // only nested types can be declared "protected"
    bool isProtected(Type t) {
        return
            !t.IsVisible
            && !t.IsPublic
            && !t.IsNotPublic
            && t.IsNested
            && !t.IsNestedPublic
            && t.IsNestedFamily
            && !t.IsNestedPrivate
            && !t.IsNestedAssembly
            && !t.IsNestedFamORAssem
            && !t.IsNestedFamANDAssem;
    }
    
    // only nested types can be declared "private"
    bool isPrivate(Type t) {
        return
            !t.IsVisible
            && !t.IsPublic
            && !t.IsNotPublic
            && t.IsNested
            && !t.IsNestedPublic
            && !t.IsNestedFamily
            && t.IsNestedPrivate
            && !t.IsNestedAssembly
            && !t.IsNestedFamORAssem
            && !t.IsNestedFamANDAssem;
    }
    

    【讨论】:

    • 可以定义内部嵌套类。所以这并不适用于所有情况。
    【解决方案4】:

    嗯,我不太确定,但是例如

    Public Function PublicFriendOrPrivate(t As Type) As String
        If t.IsPublic Then
            Return "Public"
        Else
            If t.IsNotPublic AndAlso t.IsNested Then
                Return "Private"
            Else
                Return "Friend"
            End If
        End If
    End Function
    

    '注意'朋友'在 C# 中等于'内部'。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-11
      • 2015-08-08
      • 2010-11-07
      • 1970-01-01
      • 1970-01-01
      • 2011-06-25
      • 1970-01-01
      • 2015-08-25
      相关资源
      最近更新 更多