我有 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() 不会
我不希望它自动进行验证,至少我应该决定是否应该验证它,不是吗?
无法从派生类外部访问基方法。 您可以在派生类中编写一个方法来调用基方法,如下所示:
public class B : A
{
public override void print() { Console.WriteLine("B"); }
public void basePrint() { base.print(); }
}
或者你可以使用
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>
类型的委托。
您只能通过以下方式从派生类 (
B
) 调用基类的方法:
base.print();
我认为没有办法做你想做的事情,因为它有点破坏了多态性的要点。
但是,您可以通过在 print
中执行此操作来
A
中隐藏B
方法:
new public void print() { Console.WriteLine("b"); }
这样,这段代码:
A a= new B();
a.print();
会调用
print
中的
A
。
nocodename所示,在这里我找到了类似的方法。
A a = new B();
var ptr = typeof(A).GetMethod("Print", new[] { typeof(_inputParameter) }).MethodHandle.GetFunctionPointer();
var baseGetItem = (Func<String, String>)Activator.CreateInstance(typeof(Func<String, String>), a, ptr);
String postedValue = baseGetItem(_parameter);
print
之外调用基类
B
,即从
Main
方法调用,因为
override
在 C# 中的工作方式。然而,如果你想有可能做到这一点,你应该考虑类
B
中的 shadowprint 方法:
public class B:A
{
public new void print() { Console.WriteLine("b"); }
}
使用父类中的
new
关键字类shadows 成员,因此您的代码行将起作用:
A a= new B();
a.print(); //prints "a"
和
B b= new B();
b.print(); //prints "b"
参见示例,
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");
}
}
}
希望您理解!谢谢你
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");
}
}
protected void MethodToExtend() {
SomeOtherMethod();
}
protected void SomeOtherMethod() {
// do something
}
然后,在子班上:
protected new void MethodToExtend() {
SomeOtherMethod();
// do more stuff
}
var obj = new B();
obj.Print(); // overriden method
(obj as A).Print(); // base method