Sorry for the delay, I'm a bit slow-minded. Well, I cannot understand exactly why my case is buggy, so I'll be a little more precise. Consider the following code: (file:protect1.cs) using System; namespace protect { public class A { protected void foo () { Console.WriteLine ("A.foo"); } } } (file:protect2.cs) using System; namespace protect { public class B : A { public B () { X myX = new X (this); myX.SomeMethod (); Console.Write ("Call from B: "); foo (); } private class X { A owner; public X (A Owner) {owner=Owner;} public void SomeMethod () { B _owner = owner as B; Console.Write ("Call from B.X as B: "); _owner.foo (); Console.Write ("Call from B.X as A: "); owner.foo (); } } public static void Main () { B myB = new B (); } } } This code is correct (both csc, mcs and cscc agree on that). It compiles and run, whether compiled into a unique assembly (cscc protect*.cs -o protect) or two (cscc -shared -o protect1.dll protect1.cs; cscc protect2.cs -o protect -lprotect1). It outputs: Call from B.X as B: A.foo Call from B.X as A: A.foo Call from B: A.foo exactly like expected. Now imagine that (as in my real project) I have other classes in the assembly protect1, that need to invoke foo() from outside A. For the rest of the world, foo() must remain protected. From ECMA, the way to achieve that is to declare foo() protected internal in A. The behaviour outside the assembly protect1 should not be altered (foo() should still be seen as protected). So protect1.cs becomes: using System; namespace protect { public class A { protected internal void foo () { Console.WriteLine ("A.foo"); } } } and protect2.cs remains unchanged. In this case, cscc accepts the code when compiled into a unique assembly (cscc protect*.cs -o protect). When I try separate assemblies (cscc -shared -o protect1.dll protect1.cs; cscc protect2.cs -o protect -lprotect1), the compiler outputs: protect2.cs:21: called object is not a method or delegate protect2.cs:23: called object is not a method or delegate In my undersanding, foo() should still be seen as protected, from outside the assembly protect1. Note that both csc (Microsoft) and mcs (Mono) agree with my interpretation. OK, you may reply that majority does not make truth :-)