3

我不认为这是可能的,但我很好奇。是否可以在其子类中将超类中的受保护变量设为私有。

例如,我有三个班级SuperClassSubClass : SuperClassSubCLass2 : SubClass

我希望能够访问protected string[] commands其中的变量,但阻止SuperClass从.SubClassSubClass2

如果这是不可能的,有没有办法达到同样的效果?

4

4 回答 4

7

我不认为这是可能的,但我很好奇。是否可以在其子类中将超类中的受保护变量设为私有。

不。就个人而言,我首先会避免使用变量 non-private - 我会提供 protected property。您可以创建一个新属性来“隐藏”基本属性......但这对我来说有点糟糕的设计。

想不出任何办法从孙子的角度绕过隐藏,而不改变其他课程之一,但对我来说感觉很随意:

public class Base
{
    private int foo = 5;
    protected int Foo { get { return foo; } }
}

public class Child : Base
{
    protected new int Foo { get { return 0; } }
}

public class GrandChild : Child
{
    // Aargh, can't get at the original Foo...
}

你为什么要实现这个目标?也许您应该密封您的直接子类,并强制其他类使用组合...

编辑:正如评论中所解释的,听起来这是一种将属性(我仍然会使其成为返回私有字段的属性)内部的情况是合适的。这使该属性可以访问同一程序集中的所有其他代码,但不能访问其他程序集。

于 2012-04-18T19:29:52.663 回答
0

我可以为您提供的下一件最好的事情(按照 Skeet 已经解释过的内容)是让您更难看到房产。这不是很好——也不是我将如何使用显式接口,但这是需要了解的。

 interface I
 {
   int Prop { get; set; }
 }

 class A : I
 {
   int I.Prop { get; set; }
 }

 class B : A
 {
   public void Bar()
   {
     (this as I).Prop = 2;
   }
 }

 class C : B
 {
   public void Foo()
   {
     //Prop = 1;
   }
 }
于 2012-04-18T19:57:54.653 回答
0

我认为可以为变量创建一个容器,并在 SubClass 和 SuperClass 之间共享它,如下所示:

class Prop {
    public string Str = "a string";
}
class A {
    Prop prop;
    protected A(Prop p) { prop = p; }
    public A() : this(new Prop()) { }
}
class B : A {
    Prop prop;
    private B(Prop p) : base(p) { prop = p; }
    public B() : this(new Prop()) { }
}
class C : B {
    public void Meth() {
        // has no access to prop.Str
    }
}
于 2012-04-18T20:00:44.583 回答
0

从 C# 的第一天开始,通过从基础中隐藏一个成员就可以实现这一点。特别是,您可以隐藏具有任何类型成员的成员。我觉得最自然的方式是在这个场景中隐藏字段是用方法隐藏它。

public class Base
{
  protected int Foo;
}

public class Derived : Base
{
  // Current class can access base.Foo.
  public Derived() { base.Foo = 1; }
  // Hide base.Foo for further derived classes.
  [EditorBrowsable(EditorBrowsableState.Never)]
  [Obsolete("This is used to turn a protected field into private.", true)]
  protected new void Foo() { throw new FieldAccessException(); }
}

public class FurtherDerived : Derived
{
  // In this scope, base.Foo resolves to the method Derived.Foo.
  // If you try calling it, the compiler complains.
  // It is also impossible to say base.base.Foo.
}
于 2020-10-05T03:52:23.023 回答