Is an internal and protected member possible in C #?

Consider the following classes:

public class Vehicle { ... } public class Coverage { ... } public class VehicleList : IEnumerable<Vehicle> { ... } public class CoverageList : IEnumerable<Coverage> { ... } public abstract class Quote { protected VehicleList vehicles; protected CoverageList coverages; internal Quote() { ... } public IReadOnlyCollection<Vehicle> Vehicles { get { return this.vehicles.AsReadOnly(); } } public IReadOnlyCollection<Coverage> Coverages { get { return this.coverages.AsReadOnly(); } } ... } public sealed class OhQuote : Quote { //needs to access protected fields ... } public sealed class InQuote : Quote { ... } public sealed class MiQuote : Quote { ... } 

Quote fully encapsulates the functionality of both VehicleList and CoverageList , so I would like to mark these classes as internal . The problem is that they are protected field types of the public class. If I mark these fields as protected internal , then they are protected OR internal . I really need them to be protected AND internal (with protected with priority in the assembly). You can see that neither Quote (which has an internal constructor) nor its subclasses (which are sealed ) can be extended outside the assembly. I already figured out how to achieve the desired functionality using public interfaces, but I would like to make sure that there is no more concise way.

+7
inheritance protected c # oop
source share
3 answers

Although the .NET runtime supports this concept ("FamilyAndAssembly"), C # does not currently do this.

This was suggested for C # 6.0 as a private protected access modifier, but this feature has been removed.

UPDATE: private protected was added in C # 7.2 .

+5
source share

In addition: If you do not want to use interfaces and, as you see, there is no C # support to achieve this, remember : you can always use reflection to do such strange and strange things.

You can set the field to private , and using reflection, you can assign new values ​​from anywhere, wherever you want, from derived classes in the same assembly.

+1
source share

I doubt your derived classes will access the Quote fields directly.

I ask if there is a way to achieve the desired functionality without using public interfaces.

I think you can safely change the modifiers in the fields to private , and derived classes will manipulate the fields indirectly using the protected methods defined in your base class Quote . No additional public interfaces are required.

Here is an example of how it might look:

 public class Vehicle {} public class Coverage {} // Set these as "internal" as you were hoping for... internal class VehicleList : IEnumerable<Vehicle> { public void Foo() {} } internal class CoverageList : IEnumerable<Coverage> { public void Bar() {} } public abstract class Quote { // Mark these as "private" private VehicleList vehicles; private CoverageList coverages; internal Quote() {} public IReadOnlyCollection<Vehicle> Vehicles { get { return this.vehicles.AsReadOnly(); } } public IReadOnlyCollection<Coverage> Coverages { get { return this.coverages.AsReadOnly(); } } // Add protected methods to manipulate the private fields. protected void PerformFooOnVehicles() { this.vehicles.Foo(); } protected void PerformBarOnCoverages() { this.coverages.Bar(); } } public sealed class OhQuote : Quote { // We now have indirect access to Quote private fields. public void Baz() { this.PerformBarOnCoverages(); this.PerformFooOnVehicles(); } } public sealed class InQuote : Quote {} public sealed class MiQuote : Quote {} 

This alternative performs the task of indirectly exposing VehicleList and CoverageList only to derived classes that are part of the same assembly.

+1
source share

All Articles