Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You need to have classes A and B in the same assembly and class C in another assembly. <strike>You can mark the member you want to restrict access to by derived classes as <code>protected internal</code>. This makes the member, well, protected and internal. As far as limiting class <code>C</code>'s access to the member it will suffice to mark it <code>internal</code>. Since this will make it it <code>public</code> within the first assembly, you might want to add <code>protected</code> to enforce encapsulation.</strike></p> <p>Turns out marking a member <code>protected internal</code> doesn't make it private to classes outside of the assembly. Seems that for all intents and purposes <code>protected internal</code> is the same as protected. Unfortunately the only way I can see achieving this would be to mark it internal and put up with the member being public to the defining assembly.</p> <p>Even <a href="http://msdn.microsoft.com/en-us/library/ms173121%28VS.80%29.aspx" rel="nofollow noreferrer">C# programming guide on MSDN</a> gets it wrong:</p> <blockquote> <p>By combining the protected and internal keywords, a class member can be marked protected internal — only derived types or types within the same assembly can access that member.</p> </blockquote> <p>Phil Haack <a href="http://haacked.com/archive/2007/10/29/what-does-protected-internal-mean.aspx" rel="nofollow noreferrer">explains</a>:</p> <blockquote> <p><code>protected internal</code> <strong>means</strong> <code>protected</code> <strong>OR</strong> <code>internal</code></p> <p>It’s very clear when you think of the keywords as the union of accessibility rather than the intersection. Thus <code>protected interna</code> means the method is accessible by anything that can access the <code>protected</code> method UNION with anything that can access the <code>internal</code> method.</p> </blockquote> <p>Here is the updated code:</p> <pre><code> class A { protected void Test3(){} //available to subclasses of A in any assembly protected internal void Test() { } //Same as protected :( public void Test2(){}//available to everyone internal void Test4(){} //available to any class in A's assembly } class B : A { void TestA() { Test(); //OK } } //Different assembly class C : B { void TestA() { Test4(); //error CS0103: The name 'Test4' does not exist in the current context } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload