我认为这不可行,但我很好奇。是否可以在其子类中的超类私有中创建受保护的变量。
例如,我有三个课程SuperClass
,SubClass : SuperClass
和SubCLass2 : SubClass
。
我希望能够访问来自protected string[] commands
的{{1}}中的变量SuperClass
,但阻止从SubClass
访问它。
如果无法做到这一点,无论如何都能达到同样的效果吗?
答案 0 :(得分:7)
我认为这不可行,但我很好奇。是否可以在其子类中的超类私有中创建受保护的变量。
没有。就个人而言,我会首先避免使用变量非私有 - 我提供受保护的属性。你可以创建一个新的属性来“隐藏”基本属性......但这对我来说是糟糕的设计。
我不能认为以任何方式绕过从大孩子的角度隐藏,而不改变其他类别之一,但对我来说这感觉很随意:
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...
}
为什么要实现这一目标?也许你应该密封你的直接子类,并强迫其他类使用组合代替......
编辑:正如评论中所解释的那样,听起来这是一个制作属性的情况(我仍然会使它成为返回私有字段的属性) internal 是合适的。这使得属性可以访问同一程序集中的所有其他代码,但不能访问其他程序集。答案 1 :(得分: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;
}
}
答案 2 :(得分: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
}
}
答案 3 :(得分:0)
从C#的第1天开始,可以通过从基础隐藏成员来实现。特别是,您可以隐藏具有任何类型成员的成员。我觉得最自然的方法是在这种情况下隐藏字段,就是用一种方法将其隐藏。
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.
}