Да, вы просто не можете сделать их классами верхнего уровня, они должны быть внутренними классами
public class Outer
{
protected class Foo
{
}
}
Это нормально, это означает, что единственные классы, которые могут видеть Foo, это подклассы Outer
class X
{
// 'Outer.Foo' is inaccessible due to its protection level
private void Flibble(Outer.Foo foo)
{
}
}
class X : Outer
{
// fine
private void Flibble(Outer.Foo foo)
{
}
}
Обратите внимание, что вы не можете объявить любой внешний класс как закрытый, защищенный (или защищенный внутренний) в c #, так как модификатор доступа для классов внешнего уровня определяет их видимость по отношению к другим сборкам. Видимо только в сборке (или друзьям через InternalsVisibleTo) или вне сборки.
Таким образом, хотя публичные / внутренние идентификаторы используются здесь для согласованности, на самом деле состояние в IL просто 'Public' или 'NonPublic' (как показывают флаги Reflection.Emit )