C# 有没有办法指定范围?

C# 有没有办法指定范围?,c#,inheritance,scope,C#,Inheritance,Scope,考虑以下代码示例: public abstract class Parent { public int val; public Parent() { val = 0; } public virtual void foo() { inc(); } public virtual void inc() { val = val + 10; } } public class

考虑以下代码示例:

public abstract class Parent
{
    public int val;
    public Parent()
    {
        val = 0;
    }
    public virtual void foo()
    {
        inc();
    }

    public virtual void inc()
    {
        val = val + 10;
    }
}

public class Child : Parent
{
    public override void foo()
    {
        base.foo();
    }

    public override void inc()
    {
        val++;
    }
}

static void Main(string[] args)
{
    Parent p = new Child();
    Console.WriteLine("p.val = " + p.val);  //Output: p.val = 0
    p.foo();
    Console.WriteLine("P.val = " + p.val);  //Output: p.val = 1
}

我假设父类的
inc()
没有被调用,因为
{this}
指针实际上指向一个子对象,因此将从父对象的函数
foo()
调用子版本的
inc()
。是否有一种方法来强制父函数<代码> FooWORE(/COD>)总是调用父函数“代码>代码>())/>代码>您可以在C++中使用<代码>:://Cuth>运算符> < /P> < P>子实例将调用自己的类型实现。
foo()。当然,您可以在
Parent
中编写一个非虚拟方法,并使
Parent.foo()
调用该方法,以及
Parent.inc()
的默认实现

这就是诀窍:

public abstract class Parent
{
    public int val;

    public Parent()
    {
        val = 0;
    }

    public virtual void foo()
    {
        MethodInfo method = typeof(Parent).GetMethod("inc");
        DynamicMethod dm = new DynamicMethod("BaseInc", null, new Type[] { typeof(Parent) }, typeof(Parent));
        ILGenerator gen = dm.GetILGenerator();
        gen.Emit(OpCodes.Ldarg_1);
        gen.Emit(OpCodes.Call, method);
        gen.Emit(OpCodes.Ret);

        var BaseInc = (Action<Parent>)dm.CreateDelegate(typeof(Action<Parent>));
        BaseInc(this);
    }

    public virtual void inc()
    {
        val = val + 10;
    }
}
公共抽象类父类
{
公共国际价值;
公共家长()
{
val=0;
}
公共虚拟void foo()
{
MethodInfo method=typeof(Parent).GetMethod(“inc”);
DynamicMethod dm=新的DynamicMethod(“BaseInc”,null,新类型[]{typeof(Parent)},typeof(Parent));
ILGenerator gen=dm.GetILGenerator();
gen.Emit(操作码Ldarg_1);
gen.Emit(操作码、调用、方法);
gen.Emit(操作码Ret);
var BaseInc=(Action)dm.CreateDelegate(typeof(Action));
BaseInc(本公司);
}
公共虚拟空间公司
{
val=val+10;
}
}
但这只是一个概念的证明:它非常可怕,而且完全打破了多态性


我认为你没有充分的理由写这篇文章。

你对这个问题考虑得太多了

  • 如果您想要非虚拟分派,那么首先不要将方法设置为虚拟的

  • 如果您想要虚拟和非虚拟分派,那么可以使用两种方法,一种是虚拟的,另一种是静态的

例如:

class Base
{
    protected static void NonVirtualFoo(Base b)
    {
        // Whatever
    }
    public virtual void Foo()
    {
        Base.NonVirtualFoo(this);
    }
}

class Derived : Base
{
    protected new static void NonVirtualFoo(Derived d)
    {
        // Whatever
    }
    public override void Foo()
    {
        Derived.NonVirtualFoo(this);
        Base.NonVirtualFoo(this);
    }
}

使用正确的工具进行作业。如果需要虚拟分派,则调用虚拟方法。如果需要静态分派,则调用静态方法。不要试图对虚拟方法使用锤子并使其静态调度;这与工具的全部用途背道而驰

如果Parent.inc()没有声明为“virtual”,那会怎么样?这不是破坏了拥有多态foo()的全部意义吗?即使您使用了Parent::foo(){this.inc()},它仍然会调用Child::foo。我很确定您可以使用反射来完成它。当然还有
base
关键字,它不支持C++的
支持的所有功能。你的问题是“我想要虚拟函数的非虚拟分派”。如果您想要的是非虚拟分派,那么为什么您首先将其标记为虚拟分派?请不要在标题前加上“C#”之类的前缀。这就是标记的用途。是否真的需要使用codegen,而不仅仅是使用
方法的正常反射。调用(this,null)
?@svick Yes
method.Invoke(this,null)
将调用重写的
inc
方法。