新关键字不强制隐藏 - OOP C#

new keyword not forcing hiding - OOP C#

我有以下场景:

我想模拟一个界面,以便对我的应用程序进行单元测试。我试图不创建一个新的模拟 class 实现我的接口,而是创建一个新的 class 继承原始具体 class 并使用 new 关键字在调用该方法时强制执行新行为.但是由于某种原因,正在调用具体的 classs' 方法,而不是我创建的 class(作为模拟)

以下代码:

public interface IMyService 
{ 
    Model GetModelData(int id)
}

public class MyService : IMyService
{
    public Model GetModelData(int id)
    { 
       //call to db     
    }
}

public class MyService2 : MyService
{
    public MyService2()
        : base(new MyRepository())
    {    
    }

    public new Model GetModelData(int id)
    { 
        return new Model();
    }
}

注入依赖:

x.ForRequestedType<IMyService>().TheDefaultIsConcreteType<MyService2>();

检索具体内容 class:在调试时我可以看到 myService 指向 MyService2 class 但该方法在 MyService class.

上执行
_myServie = ObjectFactory.GetInstance<IMyService>();
                Model modelData = _myServie.GetModelData(5);

只需使用 new 即可创建一个新方法,而无需将其与接口相关联。您在真实代码中使用接口(我假设),因此您希望将接口方法绑定到新方法。为此,您必须再次声明要实现该接口。这是一个显示差异的示例:

using System;

interface IFoo
{
    void Bar();
}

class Normal : IFoo
{
    public void Bar()
    {
        Console.WriteLine("Normal.Bar");
    }
}

class Extended1 : Normal
{
    public new void Bar()
    {
        Console.WriteLine("Extended1.Bar");
    }
}

class Extended2 : Normal, IFoo
{
    public new void Bar()
    {
        Console.WriteLine("Extended2.Bar");
    }
}

class Test
{
    static void Main()
    {
        IFoo x = new Extended1();
        IFoo y = new Extended2();

        x.Bar();
        y.Bar();
    }
}

输出:

Normal.Bar
Extended2.Bar

因此,如果您将 class 声明更改为:

public class MyService2 : MyService, IMyService

您应该会发现它很管用。请注意,我不能说我是这种方法的忠实拥护者 - MyService 中调用该方法的任何内容都会调用它自己的实现 除非 它碰巧通过IMyService 类型的引用。您可以在您的具体 class 虚拟中实现接口实现,并在您的 subclass 中 覆盖 它;这在某些方面会更好,但在其他方面会更糟。基本上,这种 "half-inheritance" 对我来说感觉很脆弱。

我怀疑如果你有一个抽象的基础class,你的实际实现和你的测试实现都来自......

我认为您正在寻找的是使 MyService 上的方法成为虚拟方法并在 MyService2 中覆盖它。像这样:

public interface IMyService 
{ 
    Model GetModelData(int id)
}

public class MyService : IMyService
{
    public virtual Model GetModelData(int id)
    { 
       //call to db     
    }
}

public class MyService2 : MyService
{
    public MyService2()
        : base(new MyRepository())
    {    
    }

    public override Model GetModelData(int id)
    { 
        return new Model();
    }
}

这样,如果子class中重写了方法,那么会调用子classes方法,否则基class会消耗方法调用。