C#中是否可以使用受内部AND保护的成员?

时间:2015-08-29 02:18:30

标签: c# oop inheritance protected

考虑以下课程:

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完全封装了VehicleListCoverageList的功能,因此我想将这些类标记为internal。问题是它们是protected类的public字段的类型。如果我将这些字段标记为protected internal,则它们为protectedinternal。我真正需要的是protectedinternalprotected在集会中优先)。您可以看到Quote(具有internal构造函数)及其子类(sealed)都不能扩展到程序集之外。我已经想出如何使用公共接口实现所需的功能,但是想确保没有更简洁的方法。

3 个答案:

答案 0 :(得分:5)

虽然.NET运行时支持这个概念(&#34; FamilyAndAssembly&#34;),但C#目前没有。

这是以private protected访问修饰符的形式为C#6.0提出的,但该功能已被删除。

更新: private protected已添加到C# 7.2

答案 1 :(得分:1)

作为附录: 如果您不想使用接口,并且您看到 - 没有C#支持来实现该目标,记住:您始终可以使用 反射 做那种非常奇怪和奇怪的事情。

您可以将字段设置为private并使用反射,您可以从任何位置分配新值,当然也可以从同一程序集中的派生类中分配。

答案 2 :(得分:1)

我质疑派生类是否需要直接访问$('.admin_popup').on('click',function(){ $(".light_admin,.white_overlay").slideDown("slow", function(){ $(".admin_help_popup").animate({"min-height": "380px"}, "fast"); }); }); $('.close_admin_popup').on('click',function(){ $(".admin_help_popup").css("min-height", "0px"); $(".light_admin,.white_overlay").slideUp("slow"); }); 的字段。

  

我在询问是否有办法在不使用公共接口的情况下实现所需的功能。

我认为您可以安全地将字段上的修饰符更改为Quote,并让派生类通过private中定义的protected方法操作字段间接基类。不需要额外的公共接口。

以下是它的外观示例:

Quote

此替代方案实现了间接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's private fields. public void Baz() { this.PerformBarOnCoverages(); this.PerformFooOnVehicles(); } } public sealed class InQuote : Quote {} public sealed class MiQuote : Quote {} VehicleList 暴露给属于同一程序集的派生类的目标。