Skip to content

Instantly share code, notes, and snippets.

@nohwnd
Created August 6, 2021 10:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nohwnd/eebd17f83a7498ae9d55988cddc95936 to your computer and use it in GitHub Desktop.
Save nohwnd/eebd17f83a7498ae9d55988cddc95936 to your computer and use it in GitHub Desktop.
Find internal classes
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