如何“覆盖”部分类中的方法?

时间:2013-09-19 08:02:54

标签: c#

我一直在寻找解决我们公司所遇到的复杂问题的方法。该公司是4个公司联盟的一部分,这些公司在四个“地区”覆盖我们的国家。 我们的分支在C#中开发了一个WebService,我们将这个项目分发给其他分支的开发人员。每个人都在自己的服务器中托管WebService。

现在,当公司不相处时,我一直在努力寻找你能期待的东西。我必须调整现有方法以适应我们的“区域需求”。

所以我上了这堂课:

public partial class MyClass{
     public static ComplexReturnType MyMethod(){
          // National code. Everyone uses this block of code.
     }
}

我创建了一个Regional文件夹,在将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类并在您自己的Regional类中覆盖它。

希望这有助于任何可能处于这种情况的人。

4 个答案:

答案 0 :(得分:8)

像莫里斯·斯塔姆所说的那样,封装了各种各样的东西。乍一看,我会使用策略模式: 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();

如果你把它变成一个实例方法而不是静态方法(我可能会)并决定使用像Castle Windsor这样的IoC容器,你甚至可以在配置文件中连接策略。

修改

逻辑上,每个分支都有自己的配置文件。使用这种方法有两个好处:

答案 1 :(得分:2)

您当前的方法存在一些问题。

  1. 静态方法不能是虚拟的。
  2. 你应该封装不同的内容。这意味着公司特定的代码至少应该在一个单独的类中(最好是一个单独的程序集)。您需要为基本程序集提供公司特定的代码。您可以将strategy pattern与IoC / Dependency Injection结合使用。
  3. 使基本方法虚拟包含代码的风险是重用的代码将被复制。 解决方案是创建一个包含通用代码的密封方法,该方法使用将在密封方法中调用的公司的抽象(或虚拟)方法。结合我之前的观点,这意味着调用已在注入的实例上实现的方法。
  4. 如果问题仅限于本地化,则只应使用.NET提供的解决方案(即sattelite程序集),其中包含特定于文化的资源。但是,您将4个地区划分为同一个国家/地区,因此我假设您具有特定于区域的逻辑而非本地化问题。
  5. 实现上述建议的示例代码:

    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");
        }
    }
    

答案 2 :(得分:1)

我认为你误解了部分课程的用途!创建分部类只是意味着该类的源代码被拆分为单独的文件。将所有源代码写入同一文件没有区别,所以基本上你写的是:

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.
     }
}

看到问题?

答案 3 :(得分:1)

您需要使用编译标记来避免 例如:

public partial class MyClass
    {
#if National
        public static void NationalMethod()
        {

        }
#endif

    }


    public partial class MyClass
    {
#if Regional
        public static void NationalMethod()
        {

        }
#endif
    }

在项目属性中,Build->条件编译符号:根据需求区域添加区域或国家。