当前位置:  开发笔记 > 编程语言 > 正文

有没有办法调用重写方法的父版本?(C#.NET)

如何解决《有没有办法调用重写方法的父版本?(C#.NET)》经验,为你挑选了3个好方法。

在下面的代码中,我尝试了两种方法来访问methodTwo的父版本,但结果总是2.有没有办法从ChildClass实例获得1结果而不修改这两个类?

class ParentClass
{
    public int methodOne()
    {
        return methodTwo();
    }

    virtual public int methodTwo()
    {
        return 1;
    }
}

class ChildClass : ParentClass
{
    override public int methodTwo()
    {
        return 2;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var a = new ChildClass();
        Console.WriteLine("a.methodOne(): " + a.methodOne());
        Console.WriteLine("a.methodTwo(): " + a.methodTwo());
        Console.WriteLine("((ParentClass)a).methodTwo(): "
         + ((ParentClass)a).methodTwo());
        Console.ReadLine();
    }
}

更新 ChrisW发布了这个:

从课外,我不知道任何简单的方法; 但是,也许,我不知道如果尝试反射会发生什么:使用Type.GetMethod方法查找与ParentClass中的方法关联的MethodInfo,然后调用MethodInfo.Invoke

那个答案被删除了.我想知道这个黑客是否可行,只是为了好奇.



1> Craig Stuntz..:

在里面ChildClass.methodTwo(),你可以打电话base.methodTwo().

在课堂之外,打电话((ParentClass)a).methodTwo() 打电话ChildClass.methodTwo.这就是存在虚拟方法的全部原因.



2> Marc Gravell..:

在IL级别,你可能会发出一个call而不是一个callvirt,并完成工作 - 但是如果我们将自己限制在C#;-p(编辑 darn!运行时会阻止你VerificationException:"操作可能会破坏运行时的稳定性.";删除在virtual它工作正常;太聪明了一半......)

ChildClass类型内部,您可以使用base.methodTwo()- 但是,这在外部是不可能的.你也不能超过一个级别 - 没有base.base.Foo()支持.

但是,如果使用方法隐藏禁用多态,则可以获得所需的答案,但原因很简单:

class ChildClass : ParentClass
{
    new public int methodTwo() // bad, do not do
    {
        return 2;
    }
}

现在,您可以从同一对象获得不同的答案,具体取决于变量是定义为a ChildClass还是a ParentClass.



3> Michal..:

如上所述,如果您需要在PRODUCTION代码中调用“ base.base”,则对类设计不利。但是,如果在使用无法编译的外部库的同时进行调试或搜索某些工作环境,则使用此技术是完全合法的。C#不直接提供此选项是令人不快的。仍然可以将IL生成器和Emit一起使用Kenneth Xu解决方案。有用。

class A { public virtual string foo() { return "A"; } }

class B : A { public override string foo() { return "B"; } }

// now in class C
class C : B {}      
// we can call virtual method "foo" from A using following code
MethodInfo fooA = typeof(A).GetMethod("foo", BindingFlags.Public | BindingFlags.Instance);

DynamicMethod baseBaseFoo = new DynamicMethod(
            "foo_A",
            typeof(string),
            new[] { typeof(A) },
            typeof(A));
        ILGenerator il = baseBaseFoo.GetILGenerator();
        il.Emit(OpCodes.Ldarg, 0);
        il.EmitCall(OpCodes.Call, fooA, null);
        il.Emit(OpCodes.Ret);

// call foo() from class A, it returns "A"
(string)baseBaseFoo.Invoke(null, new object[] { this });

有关参考和完整示例,请参见 http://kennethxu.blogspot.cz/2009/05/cnet-calling-grandparent-virtual-method.html

谢谢徐熙!!

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有