覆盖部分类中的虚方法

时间:2013-06-21 17:33:39

标签: c# override virtual nopcommerce partial-classes

我目前正在使用nopCommerce源代码并尽力避免编辑源代码,而是使用与源代码分开的部分类和插件,我们是否需要升级版本

我想通过在同一个程序集中使用部分类来对下订单的代码进行一些更改:

Orignal源代码:

namespace Nop.Services.Orders {

  public partial class OrderProcessingService : IOrderProcessingService {

        public virtual PlaceOrderResult PlaceOrder(ProcessPaymentRequest processPaymentRequest)
        { //....

我的部分课程:

namespace Nop.Services.Orders {

  public partial class OrderProcessingService : IOrderProcessingService {

    public override PlaceOrderResult PlaceOrder(ProcessPaymentRequest processPaymentRequest) { //....

当我尝试编译此代码时出现错误:

  

类型'Nop.Services.Orders.OrderProcessingService'已经定义了一个   名为'PlaceOrder'的成员具有相同的参数类型

但是我使用override并且原始类中的方法是virtual,有人可以告诉我这里出错的地方,以及我如何覆盖此方法?

5 个答案:

答案 0 :(得分:8)

您不能在同一个类上覆盖虚拟方法。部分类只是在不同的地方拆分定义的同一个类,它没有定义层次结构,所以这是不可能的

  

可以通过两个或多个源文件拆分类或结构的定义或接口。每个源文件都包含类定义的一部分,并且在编译应用程序时将所有部分组合在一起

您应该创建一个继承的类来实现目标

public class MyOrderProcessingService : OrderProcessingService
{
    public override PlaceOrderResult PlaceOrder(ProcessPaymentRequest processPaymentRequest) { //....
}

答案 1 :(得分:5)

不完全清楚你想要什么,但也许你可以使用 partial方法

因此,负责该班级第一部分的“政党”可以单独签名:

“Orignal源代码”:

namespace Nop.Services.Orders {

  public partial class OrderProcessingService : IOrderProcessingService {

    partial void PlaceOrder(ProcessPaymentRequest processPaymentRequest,
      ref PlaceOrderResult result);

然后,负责另一个“部分”的“方”可能会也可能不会选择提供该方法的实现。如果他们提供一个,那将是:

“我的部分班级”:

namespace Nop.Services.Orders {

  public partial class OrderProcessingService : IOrderProcessingService {

    partial void PlaceOrder(ProcessPaymentRequest processPaymentRequest,
      ref PlaceOrderResult result) {

      // actual code goes here
    }

注意事项:

  • partial方法不能为public;它必须是私有的,甚至指定private关键字也是非法的。私有方法不允许virtual
  • partial方法必须返回void,并且不能将参数标记为out,因此我们将result作为ref参数
  • 第一个“部分”中的声明有一个分号;而不是一个正文
  • 另一个“部分”中的实现(如果存在)具有方法体{ ... }

现在在“Orignal源代码”中可以像这样调用方法:

// ...
PlaceOrderResult result = null;
PlaceOrder(someRequest, ref result);
// check if 'result' was changed to something non-null, and if so use 'result'

请注意:

  • 如果该类的“部分”没有选择实现PlaceOrder,那么该方法(包括对它的所有调用!)在编译之前(精神上)从类的所有部分删除 。这也消除了对调用中参数的评估,如果评估有副作用(例如PlaceOrder(FindRequestAndCauseOtherEffects(), ref result);),这可能很重要。
  • 我之前提到的方法必须返回void且没有out参数的限制可以理解为其结果。

今天关于partial void方法的课程结束。

答案 2 :(得分:3)

您可以使用partial class来分割多个类的代码,但不能在2个分部类中拆分单个方法。你需要只在一个地方有方法。如果您想扩展功能,那么请寻找适合您的场景的其他方法,如子类或组合等。

答案 3 :(得分:3)

你做不到。 partial基本上做的是告诉C#编译器将两位代码连接在一起。

一个hacky解决方案是完成课程,然后从中继承并覆盖你想要的方法,例如:这是一个简单的例子:

public partial class A
{
    public virtual void X() { }
}
public partial class A
{
    public void Y() { }
}
public class B : A
{
    public override void X() { }
}

答案 4 :(得分:2)

问题是你在技术上仍处于同一个班级。部分类在编译时基本上是组合在一起的,所以它看到的是在同一个类中定义的两种方法。如果您使用了子类,则可以这样做,但是您不能在同一个类中定义两次方法。