How to Make a Property Protected and Internal in C#

How to make a property protected AND internal in C#?

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.

Property with internal set and protected get

Use internal for the setter and protected internal for the whole property.

public class X
{
// Read from this assembly OR child classes
// Write from this assembly
protected internal int Foo { internal set; get; }

}

The name protected internal is a bit misleading, but does what you want to achieve:

A protected internal member is accessible from the current assembly or from types that are derived from the containing class.

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/protected-internal

So, because the setter is internal, you can set the property from anywhere in the same assembly but not from a different assembly. And because the property as a whole is protected internal, you can read it from anywhere in the same assembly OR from child classes in any assembly.


Another approach:

public class X
{
// Read from child classes
// Write only from child classes in the same assembly
protected int Foo { private protected set; get; }

}

A private protected member is accessible by types derived from the containing class, but only within its containing assembly.

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/private-protected

C# internal getter, protected setter with an internal class parameter

...any protected members are visible
outside the assembly and can't use an
internal type.

-- Pent Ploompuu's answer

One way of getting around this is to make Connection public while making all its instance methods and constructors internal.

How to make a class member protected and internal?

All these answers are backwards: protected internal is available to derived classes OR other objects in the same (or InternalsVisibleTo) assembly. What you want is not possible and as Eric Lippert points out, not really useful, or at the least, something you shouldn't expect anytime soon: http://blogs.msdn.com/b/ericlippert/archive/2008/04/24/why-can-t-i-access-a-protected-member-from-a-derived-class-part-three.aspx

Using an internal type used as protected field

Create a public interface that MyAbstractClass requires and MyInternalClass implements.

Something like this so you can have it be MyInternalClass by default but inject new behavior if you needed (for example, mocking):

internal class MyInternalClass : IMyInterface
{
}

public interface IMyInterface
{
}

public abstract class MyAbstractClass
{
protected IMyInterface myField;

protected MyAbstractClass(IMyInterface required = null)
{
myField = required ?? new MyInternalClass();
}
}

How to make a property protected AND internal in C#?

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.

A tool to allow protected AND internal?

Since C# 7.2 there is construct private protected (link) that does the job.

internal protected property still accessible from a different assembly

internal protected means "internal to the assembly OR an inherited class". So yes, if you have a public class with an protected internal member, another class that inherits that type in a different assembly can still access it because of the protected modifier:

protected internal

The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly. Access from another assembly must take place within a class declaration that derives from the class in which the protected internal element is declared, and it must take place through an instance of the derived class type.

Reference: http://msdn.microsoft.com/en-us/library/ms173121.aspx

This is a limitation of the C# language. The CLR supports the "Internal AND Protected" notion. There is evidence of this with the MethodAttributes.FamANDAssem enumeration if you were emitting your own IL. If you really wanted this feature, you could do some IL post processing with something like Mono.Cecil. Why the C# language does not expose this is only a guess: little need for it.

protected internal

C# does not have any such access modifier.

However, the CLR does support it, as the FamANDAssem access level (protected internal is FamORAssem)



Related Topics



Leave a reply



Submit