Created
August 6, 2021 10:09
-
-
Save nohwnd/eebd17f83a7498ae9d55988cddc95936 to your computer and use it in GitHub Desktop.
Find internal classes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Reflection; | |
namespace ConsoleApp28 | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var ts = typeof(Program).Assembly.GetTypes().ToList(); | |
var max = ts.Max(t => t.Name.Length); | |
foreach (var t in ts) | |
{ | |
Console.WriteLine($"{t.Name.PadRight(max)} should discover: {TypeHasValidAccessibility(t.GetTypeInfo())},\tis visible: {t.IsVisible},\tis public: {t.IsPublic},\tis nested: {t.IsNested},\tis nestedPublic: {t.IsNestedPublic}"); | |
} | |
} | |
private static bool TypeHasValidAccessibility(TypeInfo type) | |
{ | |
if (type.IsVisible) | |
{ | |
// The type is public or a public nested class of entirely public container classes. | |
return true; | |
} | |
if (!true) | |
{ | |
// The type is not externally visible and internal test classes are not to be discovered. | |
return false; | |
} | |
// Either the type is not public or it is a nested class and itself or one of its containers is not public. | |
if (type.IsNested) | |
{ | |
// Assembly is CLR term for internal visibility: | |
// Private == private, | |
// FamilyANDAssembly == private protected, | |
// Assembly == internal, | |
// Family == protected, | |
// FamilyORAssembly == protected internal, | |
// Public == public. | |
// So this reads IsNestedInternal || IsNestedPublic: | |
var isNestedPublicOrInternal = type.IsNestedAssembly || type.IsNestedPublic; | |
if (!isNestedPublicOrInternal) | |
{ | |
// This type is nested, but is not public or internal. | |
return false; | |
} | |
// The type itself is nested and is public, or internal, but could be in hierarchy of types | |
// where some of the parent types is private (or other modifier that is not public and is not internal) | |
// if we looked for just public types we could just look at IsVisible, but internal type nested in internal type | |
// is not Visible, so we need to check all the parents and make sure they are all either public or internal. | |
var parentsArePublicOrInternal = true; | |
var declaringType = type.DeclaringType; | |
while (declaringType != null && parentsArePublicOrInternal) | |
{ | |
var declaringTypeIsPublicOrInternal = | |
// Declaring type is non-nested type, and we are looking for internal or public, which are the only | |
// two valid options that non-nested type can be. | |
!declaringType.IsNested | |
// Or the type is nested internal, or nested public type, but not any other | |
// like nested protected internal type, or nested private type. | |
|| declaringType.IsNestedAssembly || declaringType.IsNestedPublic; | |
if (!declaringTypeIsPublicOrInternal) | |
{ | |
parentsArePublicOrInternal = false; | |
break; | |
} | |
declaringType = declaringType.DeclaringType; | |
} | |
return parentsArePublicOrInternal; | |
} | |
// The type is not public and is not nested. Non-nested types can be only public or internal | |
// so this type must be internal. | |
return true; | |
} | |
} | |
public class PublicClass | |
{ | |
private class PrivateNestedClassInPublicClass | |
{ | |
} | |
private protected class PrivateProtectedNestedClassInPublicClass | |
{ | |
} | |
internal class InternalNestedClassInPublicClass | |
{ | |
} | |
protected class ProtectedNestedClassInPublicClass | |
{ | |
} | |
protected internal class ProtectedInteralNestedClassInPublicClass | |
{ | |
} | |
public class PublicNestedClassInPublicClass | |
{ | |
} | |
} | |
internal class InternalClass | |
{ | |
private class PrivateNestedClassInInternalClass | |
{ | |
} | |
private protected class PrivateProtectedNestedClassInInternalClass | |
{ | |
} | |
internal class InternalNestedClassInInternalClass | |
{ | |
} | |
protected class ProtectedNestedClassInInternalClass | |
{ | |
} | |
protected internal class ProtectedInteralNestedClassInInternalClass | |
{ | |
} | |
public class PublicNestedClassInInternalClass | |
{ | |
} | |
} | |
internal class InternalClass2 | |
{ | |
private class PrivateClassNestedInInternalClass | |
{ | |
public class PublicClassNestedInPrivateClassNestedInInternalClass | |
{ | |
} | |
} | |
internal class InternalClassNestedInInternalClass | |
{ | |
public class PublicClassNestedInInternalClassNestedInInternalClass | |
{ | |
} | |
internal class InternalClassNestedInInternalClassNestedInInternalClass | |
{ | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment