新关键字不强制隐藏 - 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会消耗方法调用。
我有以下场景:
我想模拟一个界面,以便对我的应用程序进行单元测试。我试图不创建一个新的模拟 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会消耗方法调用。