5

我有两节课:

public class MyBase
{
    public virtual void DoMe()
    {

    }
}

public class MyDerived:MyBase
{
    public override void DoMe()
    {
        throw  new NotImplementedException();
    }
}

我有以下代码来实例化 MyDerived:

        MyDerived myDerived=new MyDerived();

问题是如何调用基类的 DoMe?如果我使用 myDerived.DoMe(),那么将调用派生方法,从而导致异常。我尝试将 myDerived 强制转换为 MyBase,但它仍然是被调用的方法的派生版本。

编辑:如以下评论中所述,我无法更改 eitehr MyDerived 或 MyBase 因为它们不是我的代码。

4

7 回答 7

4

有一个解决方案,但很丑:使用反射来获取基类方法,然后发出调用它所需的 IL。查看这篇博文,它说明了如何做到这一点。当我所拥有的只是对覆盖该方法的派生类的引用时,我已经成功地使用这种方法来调用基类的方法实现。

于 2009-11-17T00:22:54.657 回答
3

您不能调用基类版本。

如果该方法在派生类上不起作用,那么该方法的基本版本在派生类的实例上调用时就不太可能起作用。那只是自找麻烦。该课程并非旨在以这种方式工作,您尝试做的事情可能只会导致该课程的其他部分行为不可预测。

当对象直接告诉您它不起作用时,为什么您需要在对象上调用此方法?

在我看来,这些类有一些设计缺陷,如果不允许您更改类,也许您可​​以改为更改为设计更好的库。

于 2009-01-13T05:03:18.633 回答
0
public class MyDerived:MyBase{    
    public override void DoMe()    
    {        
        base.DoMe();
    }
}

编辑:

如果不通过子类方法,则无法从“外部”访问基类方法。您唯一的选择是直接实例化您的基类并调用它的方法。

MyBase mb = new MyBase();
mb.DoMe();
于 2009-01-13T04:08:09.693 回答
0

要从外部类调用 MyBase.DoMe(),您需要 MyBase 的实例或不覆盖 DoMe() 的派生实例。声明为虚拟的方法将在对象的实际运行时类型上调用,而不是对象的类型,这就是为什么转换为 MyBase 不会改变调用的方法的原因。但是,如果该方法未在 MyBase 中声明为 virtual 并且 MyDerived 仍然实现 DoMe() ,它将“隐藏” MyBase 的实现。因此,如果引用是 MyDerived,它将调用 MyDerived.DoMe(),但在这种情况下,转换为 MyBase myBase = (MyBase)myDerived,然后调用 myBase.DoMe() 将调用 MyBase.DoMe()。

于 2009-01-13T04:08:10.553 回答
0

派生类不需要提供方法的实现。删除它,默认情况下会调用基类中的实现。

如果与您的示例不同,基类中的方法是抽象的,并且您必须提供一个实现,但派生类提供一个实现是没有意义的,那么类的设计可能有问题。

于 2009-01-13T05:54:23.023 回答
0

鉴于您的限制,存在另一种可能性:

下载 .Net 反射器。反编译现有代码,然后进行您需要的任何更改以支持您的情况。

当然,在继续之前,请检查其合法性。

于 2009-01-16T15:36:33.013 回答
0

这个问题太老了,但我没有看到以下选项:

您可以使用“新”关键字来指定重叠方法。然后,您只需将其转换为您希望调用其方法的类。

    public class MyBase
    {
        public virtual void DoMe()
        {

        }
    }

    public class MyDerived:MyBase
    {
//note the use of 'new' and not 'override'
        public new void DoMe()
        {
            throw  new NotImplementedException();
        }
    }

执行

var myDerived = new MyDerived();
var derivedDoMe = myDerived.DoMe();
var baseDoMe = ((MyBase)myDerived).DoMe();
于 2015-11-13T22:32:25.417 回答