3

关于班级设计的问题。目前我有以下结构:

抽象基础存储库类

默认存储库实现类(实现一些抽象方法,其中逻辑在所有特定类中是通用的,但其他为空)

具体的 Repository 实现类(实现上面 Default 类中留空的部分)

我现在遇到的问题是,我在特定类中有一个特定的 Update() 方法,但是当此方法中的所有代码执行来自基默认类的一些代码时,也应该执行。

我可以这样做

public override Update()
{
    // do Specific class actions and updates
    // ....

    // follow with base.Update()
    base.Update();
}

但这需要所有继承方法中的那些 base.XYZ() 调用。我可以用部分方法解决这个问题吗?

所以要求是在父类和继承类中都有代码(或者使用部分使这两个类成为一个类),并且应该执行来自两个地方的方法实现的代码。另外,如果我想扭转它并首先执行基类代码,然后是继承的类代码呢?

谢谢

4

5 回答 5

8

你有没有考虑过类似的事情:

public abstract class YourBaseClass
{
    public void Update()
    {
        // Do some stuff
        //

        // Invoke inherited class's  method
        UpdateCore();
    }

    protected abstract void UpdateCore();
}

public class YourChildClass : YourBaseClass
{
     protected override void UpdateCore()
     {
         //Do the important stuff
     }
}


//Somewhere else in code:
var ycc = new YourChildClass();
ycc.Update();
于 2010-01-13T12:07:56.350 回答
3

所有partial关键字的意思是类的定义在源文件之间拆分:

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

项目中仍然必须有一个完整的类定义。

你最好创建一个子类,这样你就可以覆盖特定的方法。

就部分方法而言(来自与上面相同的链接):

部分方法声明由两部分组成:定义和实现。它们可能位于部分类的不同部分中,也可能位于同一部分中。如果没有实现声明,则编译器会优化定义声明和对方法的所有调用。

// Definition in file1.cs
partial void onNameChanged();

// Implementation in file2.cs
partial void onNameChanged()
{
  // method body
}

您不能将一半方法放在一个文件中,另一半放在另一个文件中。

于 2010-01-13T12:05:18.463 回答
2

您可以这样做:

public sealed override void Update()
{
    UpdateCore();
    base.Update();
}

public abstract /* or virtual */ void UpdateCore()
{
    // Class-specific stuff
}
于 2010-01-13T12:05:20.940 回答
1

忘记部分,它具有完全不同的语义。虚拟基类方法的覆盖器是否应该调用基类方法不是自动的。它需要成为您文档的一部分。一个很好的例子是 Control 类中的 OnXxxx() 方法,MSDN 库文档有一个“Note to implementer”注释,警告通常需要调用基类方法。

如果您将基类方法设为抽象,那么覆盖器将非常清楚。如果不是,那么您正在强烈暗示应该这样做。如果您希望覆盖完全替换您的基本实现,那么您真的应该考虑将其抽象化。这种模糊性,再加上覆盖器通过错误覆盖而破坏基类的可能性,绝对是多态性的弱点之一。

于 2010-01-13T12:18:33.840 回答
0

向您的默认实现添加一个新的虚拟(不是抽象的,因为并非所有特定实现都需要覆盖它?)方法,以适应继承者在其自己的实现之上具有自己的附加步骤。

在默认实现的抽象方法实现中的适当位置调用虚拟方法。

您已将抽象类保持原样,并透明地增加了默认实现的灵活性。

于 2010-01-13T12:44:01.527 回答