如何“重写”分部类中的方法
本文关键字:方法 重写 如何 | 更新日期: 2023-09-27 18:31:50
我一直在寻找解决我们公司遇到的复杂问题的方法。该公司是4家公司联盟的一部分,该联盟覆盖我国四个"地区"。我们的分支用 C# 开发了一个 WebService,并将该项目分发给其他分支的开发人员。每个人都在自己的服务器中托管 Web 服务。
现在,我一直在为公司相处不好时你可以期待的事情而苦苦挣扎。我必须调整现有方法以适应我们的"区域需求"。
所以我有这个类:
public partial class MyClass{
public static ComplexReturnType MyMethod(){
// National code. Everyone uses this block of code.
}
}
我创建了一个区域文件夹,在将 DLL 分发到其他分支时,我将从编译中排除该文件夹。在这个文件夹中,我创建了文件MyClass.cs并继续这样做:
public partial class MyClass{
public static ComplexReturnType MyMethod(){
// Regional code. Only my commpany will use this.
}
}
在其他文件中调用方法 MyMethod
。我了解partial
的工作原理,但是如果不创建子类并重写其他文件中已经存在的每个调用,我就无法找到适合我需求的解决方案。
有没有人知道如何处理这个问题?
回答后编辑
我决定使用战略设计模式,当我完成时,我想"如果一个分支决定覆盖任何方法,所有其他分支都必须在其区域策略类中使用国家代码覆盖相同的方法"。
所以这不太好。相反,我这样做了:
public class VStrategy
{
public virtual ComplexReturnType MyMethod(){
// National code. Method moved from MyClass
}
public virtual AnotherReturnType MySecondMethod(){
// National code. Method moved from MyClass
}
}
public class SomeBranchStrategy: VStrategy
{
public override ComplexReturnType MyMethod() {
// Regional code for overriding a method
}
}
public class AnotherBranchStrategy: VStrategy
{
public override AnotherReturnType MySecondMethod(){ {
// Regional code for overriding a method
}
}
public class MyClass
{
private static VStrategy _strategy = new VStrategy();
public static VSTrategy Strategy { get {...}; set {...} }
public static ComplexReturnType MyMethod()
{
return Strategy.MyMethod();
}
public static ComplexReturnType MySecondMethod()
{
return Strategy.MySecondMethod();
}
}
这样,如果没有接口,每个分支都可以覆盖它们想要的任何方法,而不会对其他分支产生影响。您只需将方法代码移动到 VStrategy 类,并在您自己的区域类中重写它。
希望这对任何可能处于这种情况的人有所帮助。
就像莫里斯·斯塔姆(Maurice Stam)所说,封装变化。乍一看,我会使用策略模式:http://www.oodesign.com/strategy-pattern.html
public interface IStrategy
{
ComplexReturnType MyMethod();
}
public class NationalDefaultStrategy : IStrategy
{
public ComplexReturnType MyMethod() { }
}
public class BostonStrategy: IStrategy
{
public ComplexReturnType MyMethod() { }
}
public class MyClass
{
private static IStrategy _strategy = new NationalDefaultStrategy();
public static ISTrategy Strategy { get {...}; set {...} }
public static ComplexReturnType MyMethod()
{
return _strategy.MyMethod();
}
}
这样,您可以轻松更改运行时使用的策略
MyClass.Strategy = new BostonStrategy();
如果您将其设置为实例方法而不是静态方法(我可能会这样做)并决定使用像温莎城堡这样的 IoC 容器,您甚至可以在配置文件中连接该策略。
编辑
从逻辑上讲,每个分支都有自己的配置文件。使用此方法有两个优点:
- 所有分支将使用相同的代码库
- 您的代码将遵循 Open Closed 原则,该原则指出您的类应关闭以进行修改,并开放以进行扩展:http://en.wikipedia.org/wiki/Open/closed_principle。
您当前的方法存在一些问题。
- 静态方法不能是虚拟的。
- 您应该封装变化的内容。这意味着公司特定的代码至少应该在一个单独的类中(最好是一个单独的程序集)。 您需要为基础程序集提供公司特定的代码。您可以将策略模式与 IoC/依赖注入结合使用。 在基方法
- 包含代码时使基方法成为虚拟方法的一个风险是,重用的代码将被复制。对此的解决方案是创建一个包含通用代码的密封方法,该方法使用将从密封方法中调用的公司抽象(或空虚拟)方法。 结合我之前的观点,这意味着调用已在注入的实例上实现的方法。
- 如果问题仅限于限制本地化,则应使用包含区域性特定资源的 .NET 提供的解决方案(即卫星程序集)。但是,您将同一个国家/地区划分为 4 个区域,因此我假设您有特定于区域的逻辑而不是本地化问题。
实现上述建议的示例代码:
public class SharedClass
{
private readonly IRegionCode m_RegionLogic;
// Constructor with dependency injection
public SharedClass(IRegionCode mRegionLogic)
{
this.m_RegionLogic = mRegionLogic;
}
// Method called by the webservice
public void YourMethod()
{
// reused base logic here
Trace.Write("Somehting");
// Invoke region specific code
m_RegionLogic.Foo();
// reused base logic here
Trace.Write("Somehting");
}
}
// Contract for regions to implement
public interface IRegionCode
{
void Foo();
}
// Example of an injected class
public class FirstRegionCode : IRegionCode
{
public void Foo()
{
Trace.Write("Bar");
}
}
我想你误解了部分类的用途!创建分部类只是意味着该类的源代码被拆分为单独的文件。将所有源代码写入同一个文件没有区别,所以基本上你写的是:
public class MyClass{
public static ComplexReturnType MyMethod(){
// National code. Everyone uses this block of code.
}
public static ComplexReturnType MyMethod(){
// Regional code. Only my commpany will use this.
}
}
看到问题了吗?
需要使用编译标签来避免例如:
public partial class MyClass
{
#if National
public static void NationalMethod()
{
}
#endif
}
public partial class MyClass
{
#if Regional
public static void NationalMethod()
{
}
#endif
}
在"项目属性"中,"生成->条件编译符号":根据所需区域添加"区域"或"国家"。