c#方法继承到直接子

本文关键字:方法 继承 | 更新日期: 2023-09-27 18:13:22

我有以下类:

public class Essentials 
{
    public void DoSomething() 
    {
         //doing base stuff...
    }
}
public class NetworkEssentials : Essentials 
{
    public void DoNetworkSomething()
    {
        //doing something
    }
}
public class someClass : NetworkEssentials
{
    public void DoSomeSomething()
    {
        base.DoSomething(); //The thing I would like to prevent, as to block this from happening.
//attention: i dont want to change methods names so it will call the first parent, i still want to maintain a different method names to each class type
    }
}

我想防止someClass能够调用其父类的父类中的方法,只允许直接继承类调用其基方法。

有办法吗?

附加说明:

基本上,我有一些强制字段,我要求每个对象都有,但有一些对象,不是全部,我要求有一个额外的强制字段。我们称它们为1 2 3,而1是上父结点。我希望类3调用类2的方法,而这个类2的方法将调用类1的方法,因为只有类2有这个"额外"字段。类1不能处理这个字段,因为它根本不能识别它

c#方法继承到直接子

您可以使用internalNetworkEssentials在同一程序集中。(虽然。net确实有internalprotected交集的访问类型,这在这里是完美的,c#没有,所以你必须使用internal[更新:从c# 7.2开始,现在有private protected使用该交集])。

你可以:

public class NetworkEssentials : Essentials 
{
  new protected void DoSomething() 
  {
    throw new InvalidOperationException();
  }
}

所以DoSomething在子进程中是隐藏的。(它不能在Essentials中公开,否则someClass可以像其他代码一样看到它)。

仍然可以通过一些复杂的方法获得DoSomething,并且它不提供编译时块。

基本上,我有一些强制字段,我要求每个对象都有,但有一些对象,不是全部,我要求有一个额外的强制字段。我们称它们为1 2 3,而1是上父结点。我希望类3调用类2的方法,而这个类2的方法将调用类1的方法,因为只有类2有这个"额外"字段。类1不能处理这个字段,因为它根本不能识别它

好吧,那就解决这个问题。如果NetworkEssentials知道如何正确调用DoSomething(),只需适当地覆盖DoSomething():

public class Essentials
{
  public virtual void DoSomething()
  {
    //Do stuff with field 1
  }
}
public class NetworkEssentials : Essentials
{
  public override void DoSomething()
  {
    base.DoSomething(); // handle field 1
    // Code to handle other fields either here, before the call to base.DoSomething(), or both.
  }
}

不要试图阻止对DoSomething()的调用,而是使用虚拟方法来确保它们做正确的事情。这是必要的,因为调用DoSomething()的非继承代码仍然需要正确的行为。

我认为你正在寻找virtual -如果你在派生类中重写方法,那么派生类的子类只能调用派生的实现(并且绝对没有办法调用顶层一):

public class Essentials 
{
    virtual public void DoSomething() 
    {
         //doing base stuff...
    }
}
public class NetworkEssentials : Essentials 
{
    override public void DoSomething() 
    {
       base.DoSomething();
       // and other struff
    }
    public void DoNetworkSomething()
    {
        //doing something
    }
}
public class someClass : NetworkEssentials
{
    public void DoSomeSomething()
    {
        // can ONLY call nearest parent's that implements DoSomething 
        // so next calls NetworkEssentials.DoSomething 
        base.DoSomething(); 
    }
}

您可以为您想要覆盖的基类中的任何方法添加新的实现。在这种情况下,您可以在networkessentials中为Dosomething提供一个新的实现,并且对该方法的任何派生类调用都只会通过networkessentials。它不会阻止你调用方法但是你可以阻止它直接调用基类我猜这就是你想要做的

public class Essentials
{
    public void DoSomething() 
    {
         //doing base stuff...
    }
}
public class NetworkEssentials : Essentials
{
    public void DoNetworkSomething()
    {
        //doing something
    }
    protected new void DoSomething() 
    {
         
    }
}
public class someClass : NetworkEssentials
{
    public void DoSomeSomething()
    {
        base.DoSomething(); //This will go thru NetworkEssentials and not directly to Dosomething
    }
}

我不知道是什么问题。难道不能用普通的虚拟和重载方法解决这个问题吗?

public class Essentials 
{
    public virtual void DoSomething() 
    {
         //do what needs to be done at this level
    }
}
public class NetworkEssentials : Essentials 
{
    public override void DoSomething()
    {
        //do what needs to be done at this level
        base.DoSomething(); //launch what needs to be done at Essentials' level.
    }
}
public class someClass : NetworkEssentials
{
    public override DoSomething()
    {
        //do what needs to be done at this level
        base.DoSomething(); //launch what needs to be done at NetworkEssentials' level.
    }
}
注意,这样,派生类只能调用父类的实现。你不可能跳过层次结构中的一个级别,让SomeClass直接调用Essentials.DoSomething,而绕过NetworkEssentials.DoSomething

这个例子将链式执行你的DoSomething逻辑从上到下(从最派生到最少派生)。从下到上链接执行同样容易,只需在特定于每个类的逻辑之前而不是之后调用基本实现。

更新

你可以稍微滥用一下类型系统来获得你想要的行为:

public class Essentials
{
    private void DoSomething()
    {
        //doing base stuff...
    }
    public class NetworkEssentials : Essentials
    {
        public void DoNetworkSomething()
        {
            //doing something
            base.DoSomething(); //Perfectly OK
        }
    }
}
public class SomeClass : Essentials.NetworkEssentials
{
    public void DoSomeSomething()
    {
       base.DoSomething(); //Compile time error
    }
}

这整个设置看起来很奇怪,但我没有多少信息可以评估,如果这真的是合理的

不行,对于那个继承结构,你不能这样做。正如@MobyDisk所指出的,你可以考虑使用组合而不是继承来完成这个任务。

您可以将方法标记为protected来限制对派生类的访问,但是没有办法强制派生类的派生类不具有访问权。

有道理,真的。如果你有一个Animal和一个Eat方法,Dog可以访问它,Beagle也应该可以访问它(Dog派生)。

即使使用方法隐藏也不起作用。

public class Essentials
{
    protected void DoSomething()
    {
        //doing base stuff...
    }
}
public class NetworkEssentials : Essentials
{
    public void DoNetworkSomething()
    {
        //doing something
    }
    private new void DoSomething()
    {
    }
}
public class someClass : NetworkEssentials
{
    public void DoSomeSomething()
    {
        base.DoSomething(); //The thing I would like to prevent
    }
}

可以正常编译