如何使子派生 类 无法访问成员?
How do you make members inaccessible to sub-derived classes?
假设我有这样一个基础class:
public abstract class MyBaseClass
{
protected void MyMethod(string myVariable)
{
//...
}
}
然后我在一个单独的程序集中继承这个class:
public abstract class MyDerivedClass : MyBaseClass
{
static readonly string MyConstantString = "Hello";
protected void MyMethod()
{
MyMethod(MyConstantString);
}
}
我现在想确保从 MyDerivedClass
继承的任何其他 class 无法访问 MyBaseClass.MyMethod()
方法。 (澄清一下,我仍然希望能够不带参数调用 MyDerivedClass.MyMethod()
)
我尝试使用 protected internal
,但没有用。
更新:我正在尝试这样做,因为我正在处理的应用程序有一堆使用基础 class 的独立程序。有 5 个不同的 "types" 程序,每个程序都执行一个特定的、独立的功能,但它们都有一些我试图抽象到这个基础 class 中的通用代码。通用代码 99% 相同,只是根据调用它的程序类型略有不同。这就是为什么我的基 class 在示例中采用字符串参数,然后在派生基 class 中消失,因为 class 知道它执行角色 x 所以它告诉它的基 class相应地。
然后我会在 MyDerivedClass
中使用组合而不是继承。所以从这个 class 派生的所有 classes 都不知道 MyBaseClass
的方法。 class MyBaseClass
我会让包可见所以不可能使用它。
abstract class MyBaseClass
{
void MyMethod(string myVariable)
{
//...
}
}
abstract class MyDerivedClass
{
static readonly string MyConstantString = "Hello";
private MyBaseClass baseClass;
MyDerivedClass(MyBaseClass baseClass)
{
this.baseClass = baseClass;
}
protected void MyMethod()
{
baseClass.MyMethod(MyConstantString);
}
}
class 名称当然应该更改。
这不太可能。这可能表明您的对象设计可能有问题,但这不是 SO 的问题。
不过,您可以尝试更卑鄙的方法:
public abstract class MyBaseClass
{
protected abstract string MyConstantString { get; }
protected void MyMethod()
{
//...
}
}
public abstract class MyDerivedClass : MyBaseClass
{
protected override sealed string MyConstantString => "Hello";
}
或者,更典型的是,只使用构造函数传递所需的参数:
public abstract class MyBaseClass
{
private readonly string myString;
protected MyBaseClass(string myString)
{
this.myString = myString;
}
protected void MyMethod()
{
//...
}
}
public abstract class MyDerivedClass : MyBaseClass
{
protected MyBaseClass() : base("Hello") {}
}
从 MyDerivedClass
派生的 类 在任何一种情况下都无法更改参数,从继承的角度来看,第二种方法更好一些(基本上,该类型是对参数的闭包它的祖先类型)。
您无法停止通过调用此方法继承 classes - 您已经做到了 protected
因此您的意图是让继承自它的 classes 可以访问它,无论是直接还是通过另一个子class.
如果你想保留继承,你能做的最好的事情就是在子class在MyDerivedClass
中调用它时抛出一个错误:
public abstract class MyBaseClass
{
protected void MyMethod(string myVariable)
{
Console.WriteLine(myVariable);
}
}
public abstract class MyDerivedClass : MyBaseClass
{
static readonly string MyConstantString = "Hello";
protected void MyMethod()
{
base.MyMethod(MyConstantString);
}
protected new void MyMethod(string myVariable)
{
throw new Exception("Not allowed");
}
}
public class SubDerivedClass : MyDerivedClass
{
static readonly string MyConstantString = "Hello";
public void Foo()
{
MyMethod(MyConstantString);
}
}
当Foo()
在SubDerivedClass
中调用时,它会在DerivedClass
中调用MyMethod
,这将抛出异常。
假设我有这样一个基础class:
public abstract class MyBaseClass
{
protected void MyMethod(string myVariable)
{
//...
}
}
然后我在一个单独的程序集中继承这个class:
public abstract class MyDerivedClass : MyBaseClass
{
static readonly string MyConstantString = "Hello";
protected void MyMethod()
{
MyMethod(MyConstantString);
}
}
我现在想确保从 MyDerivedClass
继承的任何其他 class 无法访问 MyBaseClass.MyMethod()
方法。 (澄清一下,我仍然希望能够不带参数调用 MyDerivedClass.MyMethod()
)
我尝试使用 protected internal
,但没有用。
更新:我正在尝试这样做,因为我正在处理的应用程序有一堆使用基础 class 的独立程序。有 5 个不同的 "types" 程序,每个程序都执行一个特定的、独立的功能,但它们都有一些我试图抽象到这个基础 class 中的通用代码。通用代码 99% 相同,只是根据调用它的程序类型略有不同。这就是为什么我的基 class 在示例中采用字符串参数,然后在派生基 class 中消失,因为 class 知道它执行角色 x 所以它告诉它的基 class相应地。
然后我会在 MyDerivedClass
中使用组合而不是继承。所以从这个 class 派生的所有 classes 都不知道 MyBaseClass
的方法。 class MyBaseClass
我会让包可见所以不可能使用它。
abstract class MyBaseClass
{
void MyMethod(string myVariable)
{
//...
}
}
abstract class MyDerivedClass
{
static readonly string MyConstantString = "Hello";
private MyBaseClass baseClass;
MyDerivedClass(MyBaseClass baseClass)
{
this.baseClass = baseClass;
}
protected void MyMethod()
{
baseClass.MyMethod(MyConstantString);
}
}
class 名称当然应该更改。
这不太可能。这可能表明您的对象设计可能有问题,但这不是 SO 的问题。
不过,您可以尝试更卑鄙的方法:
public abstract class MyBaseClass
{
protected abstract string MyConstantString { get; }
protected void MyMethod()
{
//...
}
}
public abstract class MyDerivedClass : MyBaseClass
{
protected override sealed string MyConstantString => "Hello";
}
或者,更典型的是,只使用构造函数传递所需的参数:
public abstract class MyBaseClass
{
private readonly string myString;
protected MyBaseClass(string myString)
{
this.myString = myString;
}
protected void MyMethod()
{
//...
}
}
public abstract class MyDerivedClass : MyBaseClass
{
protected MyBaseClass() : base("Hello") {}
}
从 MyDerivedClass
派生的 类 在任何一种情况下都无法更改参数,从继承的角度来看,第二种方法更好一些(基本上,该类型是对参数的闭包它的祖先类型)。
您无法停止通过调用此方法继承 classes - 您已经做到了 protected
因此您的意图是让继承自它的 classes 可以访问它,无论是直接还是通过另一个子class.
如果你想保留继承,你能做的最好的事情就是在子class在MyDerivedClass
中调用它时抛出一个错误:
public abstract class MyBaseClass
{
protected void MyMethod(string myVariable)
{
Console.WriteLine(myVariable);
}
}
public abstract class MyDerivedClass : MyBaseClass
{
static readonly string MyConstantString = "Hello";
protected void MyMethod()
{
base.MyMethod(MyConstantString);
}
protected new void MyMethod(string myVariable)
{
throw new Exception("Not allowed");
}
}
public class SubDerivedClass : MyDerivedClass
{
static readonly string MyConstantString = "Hello";
public void Foo()
{
MyMethod(MyConstantString);
}
}
当Foo()
在SubDerivedClass
中调用时,它会在DerivedClass
中调用MyMethod
,这将抛出异常。