重写一个静态方法
我通过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; } }
- dependency injectionangular色对象。
公共类MockRoleService:RolesService {
public MockRoleService () { Roles = OverridenRolesObjectThatAlwaysReturnsTrue; }
}
为什么不使用属性来访问静态值? 那么它将支持inheritance并被覆盖。 这似乎是你在找什么。
public class StaticOverride { public virtual string MyVal { get { return MyStaticMethod(); } } public string MyStaticMethod () { return "Example"; } }