重写一个静态方法

我通过inheritanceRolesService来扩展一个新类。 在RolesService中,我有一个静态方法,我想在新派生类中重写。 当我从派生对象进行调用时,它不使用重载的静态方法,它实际上调用基类方法。 有任何想法吗?

public class RolesService : IRolesService { public static bool IsUserInRole(string username, string rolename) { return Roles.IsUserInRole(username, rolename); } } public class MockRoleService : RolesService { public new static bool IsUserInRole(string username, string rolename) { return true; } } 

做下面的将允许你解决静态调用。 在你想使用代码的地方,通过dependency injection来获得一个IRolesService,然后当你需要MockRolesService的时候,你可以通过它。

 public interface IRolesService { bool IsUserInRole(string username, string rolename); } public class RolesService : IRolesService { public bool IsUserInRole(string username, string rolename) { return Roles.IsUserInRole(username, rolename); } } public class MockRoleService : IRolesService { public bool IsUserInRole(string username, string rolename) { return true; } } 

你不能重载一个静态方法。 静态方法不能是虚拟的,因为它与类的实例无关。

派生类中的“overriden”方法实际上是一个新的方法,与基类中定义的方法(因此是new关键字)无关。

你不能重载一个静态方法。

如果你仔细想一想,那真的没有道理; 为了有虚拟调度,你需要一个对象的实际实例来检查。

静态方法也不能实现一个接口; 如果这个类正在实现一个IRolesService接口,那么我会争辩说,该方法不应该是静态的。 有一个实例方法是更好的devise,所以当你准备好的时候,你可以用一个真正的服务来replace你的MockRoleService

你不能重载一个静态方法。 你可能会发现这是一个有趣的阅读。

为了调用一个静态方法,你需要直接引用这个types:

 RolesService.IsUserInRole(...); 

在这种情况下,如果您希望能够调用“派生”类的静态方法,那么删除“new”关键字将允许您:

 MockRoleService.IsUserInRole(...); 

并获得预期的函数调用。

我的猜测是,这不是你要找的。 你可能在代码中有一些像前一个一样的调用,你希望通过使用Mocking工具来创build一个MockRoleService,你将注入这个新的“types”来代替旧的。 不幸的是,这不是如何与静力学。

一个嘲笑工具将创build一个嘲笑types的实例,并将注入的地方,而不是一个调用来构build真正的types。 对静态方法的调用会跳过所有这些。

就像Aaronaught提到的那样,你应该使这个方法成为一个普通的实例方法。 这将允许您的模拟服务被正确地注入到您的常规RolesService位置,允许您将方法声明移动到IRolesService接口中,并在您的MockRoleService实现中覆盖它。 然后,在“获取”RolesService的代码中,只需调用实例成员而不是静态成员即可。

 IRolesService svc = MyServiceInjector.GetService<IRolesService>(); svc.IsUserInRole(...); 

那么这样的事情呢?

 public interface IRolesService { bool IsUserInRoleImpl(string username, string rolename); } public abstract class RolesServiceBase<T> where T : IRolesService, new() { protected static T rolesService = new T(); public static bool IsUserInRole(string username, string rolename) { return rolesService.IsUserInRoleImpl(username, rolename); } } public class RolesService : RolesServiceBase<RolesService>, IRolesService { public bool IsUserInRoleImpl(string username, string rolename) { return Roles.IsUserInRole(username, rolename); } } public class MockRoleService : RolesServiceBase<MockRoleService>, IRolesService { public bool IsUserInRoleImpl(string username, string rolename) { return true; } } 

我有一个类似的问题。 我没有使用inheritance或接口,而只是使用委托。

  public class RolesService { static RolesService() { isUserInRoleFunction = IsUserInRole; } public static delegate bool IsUserInRoleFunctionDelegate(string username, string rolename); public static IsUserInRoleFunctionDelegate isUserInRoleFunction { get; set; } private bool IsUserInRole(string username, string rolename) { return Roles.IsUserInRole(username, rolename); } } 

如果您想将testing方法更改为“newMethod”,只需调用

  RolesService.isUserInRoleFunction = newMethod; 

静态方法表示与types本身相关的逻辑。 一旦从该typesinheritance,父types的静态方法就不能被假定为适用。 你可以做的是以下几点:

 public class RolesService : IRolesService { public static bool IsUserInRole(string username, string rolename) { return Roles.IsUserInRole(username, rolename); } // call this guy within the class protected virtual bool DoIsUserInRole(string username, string rolename) { return IsUserInRole(username, rolename); } } public class MockRoleService : RolesService { public new static bool IsUserInRole(string username, string rolename) { return true; } protected override bool DoIsUserInRole(string username, string rolename) { return IsUserInRole(username, rolename); // invokes MockRoleService.IsUserInRole // or simply return true; } } 

有两种方法可以使你的模拟对象工作:

1:将您的父对象的签名从RolesService更改为IRolesService(假定您尚未使用该接口)。 然后实现模拟IRolesService而不是RolesService。

 public class MockRoleService : IRolesService { public new static bool IsUserInRole(string username, string rolename) { return true; } } 
  1. dependency injectionangular色对象。

公共类MockRoleService:RolesService {

 public MockRoleService () { Roles = OverridenRolesObjectThatAlwaysReturnsTrue; } 

}

为什么不使用属性来访问静态值? 那么它将支持inheritance并被覆盖。 这似乎是你在找什么。

 public class StaticOverride { public virtual string MyVal { get { return MyStaticMethod(); } } public string MyStaticMethod () { return "Example"; } }