首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在C#中从派生类实例调用基方法?

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

Stack Overflow用户
提问于 2017-05-05 06:22:34
回答 8查看 11.9K关注 0票数 3

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

代码语言:javascript
复制
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#中做什么,有什么建议吗?

此外,感谢大家都参加了这次讨论,我想澄清为什么我需要这样的行为:

IPostBackDataHandler框架中,我们有一个接口.net来处理回发。里面有一种方法

代码语言:javascript
复制
public bool LoadPostData( string postDataKey, NameValueCollection postCollection )

当我实现它并进行测试时,有时我发现给定的回发类型postCollectionNameValueCollection,而其他时候是HttpValueCollection (NameValueCollection的派生类)

那么,如果它是一种类型的HttpValueCollection,,当我从它得到项目,例如。postCollection'ControlID'和我在此控件中输入html,HttpValueCollection.get_item()将始终验证输入并将其视为缺陷。而NameValueCollection.get_item()不会

我不希望它自动地操作验证,至少 I 应该决定它是否应该被验证,应该吗?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2017-05-05 06:30:56

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

代码语言:javascript
复制
public class B : A
{
    public override void print() { Console.WriteLine("B"); }

    public void basePrint() { base.print(); }
}

或者您可以使用Reflection来获得基本方法定义并调用它,但这是相当丑陋的。下面是如何创建调用基本DynamicMethod方法的print

代码语言:javascript
复制
// 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<parameterTypesFunc<returnType, parameterTypes>类型的委托。

票数 4
EN

Stack Overflow用户

发布于 2017-05-05 06:28:32

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

代码语言:javascript
复制
base.print();

我不认为有办法去做你想做的事,因为它打破了多态点。

但是,可以通过在print中使用B隐藏A中的B方法。

代码语言:javascript
复制
new public void print() { Console.WriteLine("b"); }

这样,这个代码:

代码语言:javascript
复制
A a= new B();
a.print();

将调用print in A

票数 3
EN

Stack Overflow用户

发布于 2017-05-08 02:15:37

感谢大家!最后,我意识到这种行为需要使用反射和委托,比如nocodename显示,这里我发现了一个类似的方法。

代码语言:javascript
复制
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);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43797869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档