如何在C#中从派生类实例调用基方法?

时间:2017-05-05 06:22:34

标签: c# inheritance

我有C#代码,基础class A和派生class B

public class A
{
    public virtual void print() {Console.WriteLine("a"); }
}
public class B:A
{
    public override void print() { Console.WriteLine("b"); }
}

static void Main(string[] args)
{
    A a= new B();
    //In c++ I can use .Base:: to call base method from derived class instance
    a.Base::print();
}

我无法修改这两个课程,而且我不知道在C#中我能做些什么,有什么建议吗?

此外,感谢大家参与此讨论,我想澄清为什么我需要这种行为:

在.net框架中,我们有一个接口 IPostBackDataHandler 来处理回发。并且有一个方法

public bool LoadPostData( string postDataKey, NameValueCollection postCollection )

当我实现它并进行测试时,我发现有时回复类型的 postCollection NameValueCollection ,而有时它的 HttpValueCollection NameValueCollection 的派生类)

然后,如果它是 HttpValueCollection 的类型,当我从中获取项目时,例如。 postCollection [' ControlID'] ,我在此控件中输入 html HttpValueCollection.get_item()将始终验证输入并将其视为缺陷。虽然 NameValueCollection.get_item()赢了

我不希望它自动运行验证,至少应该决定是否应该验证,我应该吗?

7 个答案:

答案 0 :(得分:2)

您只能通过执行以下操作从派生类(B)调用基类的方法:

base.print();

我认为没有办法做你想做的事情,因为它打破了多态性的重点。

但是,您可以print中的A 隐藏 B方法:

new public void print() { Console.WriteLine("b"); }

这样,这段代码:

A a= new B();
a.print();

将调用print中的A

答案 1 :(得分:2)

无法从派生类外部访问基本方法。 您可以在派生类中编写一个方法,该方法将调用基类方法,如下所示:

Reflection

或者您可以使用DynamicMethod来获取基本方法定义并调用它,但它相当难看。 以下是如何创建调用基本print方法的// Get MethodInfo of the base method var methodInfo = typeof(A).GetMethod("Print", BindingFlags.Instance | BindingFlags.Public); // Create DynamicMethod based on the methodInfo var dynamicMethod = new DynamicMethod("BasePrint", methodInfo.ReturnType, new[] { methodInfo.DeclaringType }, methodInfo.DeclaringType); // Create ILGenerator for the dynamic method var il = dynamicMethod.GetILGenerator(); // Emit argument with index 0 - DeclaringType il.Emit(OpCodes.Ldarg_0); // Emit method call il.EmitCall(OpCodes.Call, methodInfo, null); // Emit method return value il.Emit(OpCodes.Ret); // Invoke method with target... var b = new B(); dynamicMethod.Invoke(null, new object[] {b}); // ... or create a delegate and invoke method without target var action = dynamicMethod.CreateDelegate(typeof(Action)) as Action; action.Invoke();

DeclaringType

请注意它仅适用于无参数方法。如果你想用参数调用方法,你必须将它们的类型放入带有Action<parameterTypes的数组中,然后发出所有这些类型。如果方法返回某些内容,您还必须创建Func<returnType, parameterTypes>或{{1}}类型的委托。

答案 2 :(得分:0)

由于print在c#中的工作方式,您无法在B类之外调用基础Main,即override方法。但是,如果您希望有可能这样做,则应考虑在课程B中使用 shadow 打印方法:

public class B:A
{
    public new void print() { Console.WriteLine("b"); }
}

来自父类的new关键字类阴影成员,因此您的代码行将起作用:

A a= new B();
a.print(); //prints "a"

B b= new B();
b.print(); //prints "b"

答案 3 :(得分:0)

当您在继承中覆盖它时,无法调用基本方法。您可以将B中的方法设为new而不是override,但您将失去实施。

`public class A
{
    public virtual void print() {Console.WriteLine("a"); }
}
public class B:A
{
    public new void print() { Console.WriteLine("b"); }
}`

这种方式,当你打电话

`static void Main(string[] args)
{
    A a= new B();
    a.print(); // prints "a"
}`

否则你可以在重写方法中执行base.print。

`public class A
{
    public virtual void print() {Console.WriteLine("a"); }
}
public class B:A
{
    public override void print() 
    {
        base.print();
        Console.WriteLine("b"); 
    }
}`

答案 4 :(得分:0)

覆盖的整个想法是你不会调用基类的功能。 如果你想调用A.print - 使用A对象,如果你想调用B.print使用B对象,如果你想要一个可以使用其中一些的对象,那么 - 单独创建或使用不同的函数名称,可能会解决您的问题。

我不确定你要在这里完成什么,但也许你想了解Visitor Pattern

祝你好运!

答案 5 :(得分:0)

您可以使用“base”keywork从派生类中调用基类方法:

参见示例,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            B obj= new B();
            obj.print();
            Console.ReadKey();
        }
    }

    public class A
    {
        public virtual void print() { Console.WriteLine("a"); }
    }
    public class B : A
    {
        public override void print() 
        {
            base.print();
            Console.WriteLine("b"); 
        }
    }

}
希望你明白!谢谢你

答案 6 :(得分:-3)

var obj = new B();
obj.Print(); // overriden method
(obj as A).Print(); // base method