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 Yesmethod.Invoke(this,null)
将调用重写的inc
方法。