Here is my shortened abstract class:
abstract class Report { protected internal abstract string[] Headers { get; protected set; } }
Here is a derived class:
class OnlineStatusReport : Report { static string[] headers = new string[] { "Time", "Message" } protected internal override string[] Headers { get { return headers; } protected set { headers = value; } } internal OnlineStatusReport() { Headers = headers; } }
The idea is, I want to be able to call Report.Headers
from anywhere in the assembly, but only allow it to be set by derived classes. I tried making Headers
just internal, but protected does not count as more restrictive than internal. Is there a way to make Headers internal and its set accessor protected AND internal?
I feel like I'm grossly misusing access modifiers, so any design help would be greatly appreciate.
The protected internal keyword combination is a member access modifier. A protected internal member is accessible from the current assembly or from types that are derived from the containing class. For a comparison of protected internal with the other access modifiers, see Accessibility Levels.
protected: The type or member can be accessed only by code in the same class , or in a class that is derived from that class . internal: The type or member can be accessed by any code in the same assembly, but not from another assembly.
internal means that it's only accessible to other classes which are in the same assembly. Public means it's available to all other classes. There is no technical difference between the two.
The internal keyword is an access modifier for types and type members. This page covers internal access. The internal keyword is also part of the protected internal access modifier. Internal types or members are accessible only within files in the same assembly, as in this example: C# Copy.
It's not possible in C#.
Just for the sake of completeness, this is supported in IL (family and assembly access modifier).
What's wrong with making the getter public? If you declare the property as
public string[] Headers { get; protected set; }
it meets all of the criteria you want: all members of the assembly can get the property, and only derived classes can set it. Sure, classes outside the assembly can get the property too. So?
If you genuinely need to expose the property within your assembly but not publicly, another way to do it is to create a different property:
protected string[] Headers { get; set; } internal string[] I_Headers { get { return Headers; } }
Sure, it's ugly decorating the name with that I_
prefix. But it's kind of a weird design. Doing some kind of name mangling on the internal property is a way of reminding yourself (or other developers) that the property they're using is unorthodox. Also, if you later decide that mixing accessibility like this is not really the right solution to your problem, you'll know which properties to fix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With