Я расширяю новый класс путем наследования RolesService. В RolesService у меня есть статический methog, что я хотел бы переопределить в моем недавно производный класс. Когда я выполняю вызов от своего производного объекта, он не использует переопределенный статический метод, который он на самом деле называет методом базового класса. Какие-либо идеи?
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;
}
}
Делать следующие то, что позволит вам работать вокруг статического вызова. Если вы хотите использовать код, возьмите Irolesservice с помощью инъекций зависимости, тогда, когда вам нужен маслоолессий, вы можете пропустить это в
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;
}
}
Вы не можете переопределить статический метод. Статический метод не может быть виртуальным, поскольку оно не связано с экземпляром класса.
Метод «переопределения» в полученном классе на самом деле является новым методом, не связанным с одним, определенным в базовом классе (отсюда NEW
ключевое слово).
Статический метод представляет логику, относящуюся к самому типу. После того, как вы наследуете от этого типа, статические методы родительского типа не могут быть применены. Что вы можете сделать, это следующее:
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;
}
}
Вы не можете переопределить статический метод.
Если вы думаете об этом, это не имеет смысла; Для того, чтобы иметь виртуальную рассылку, вам нужен фактический экземпляр объекта для проверки.
Статический метод также не может реализовать интерфейс; Если этот класс реализует интерфейс IROLESSERVICE
, то я бы утвердовал, что метод не должен быть статичным вообще. Это лучший дизайн, чтобы иметь метод экземпляра, поэтому вы можете поменять ваш Mockroleservice
с реальной службой, когда вы будете готовы.
Вы не можете переопределить статический метод. Вы можете найти это Интересно прочитано.
Существует два способа сделать работу вашего Mock Object:
1: измените подпись вашего родительского объекта из RoLesservice в Irolesservice (при условии, что вы уже не используете интерфейс). Затем внедряйте издевательства в Irolesservice вместо RoLesservice.
public class MockRoleService : IRolesService
{
public new static bool IsUserInRole(string username, string rolename)
{
return true;
}
}
Публичный класс Mockrozeervice: RoLesservice {
public MockRoleService ()
{
Roles = OverridenRolesObjectThatAlwaysReturnsTrue;
}
}
Для того, чтобы вызвать статический метод, вам понадобится прямая ссылка на тип:
RolesService.IsUserInRole(...);
, в этом случае, если вы хотите иметь возможность, и вызовите статическую статичку «производной» Метод, падение ключевого слова "New" позволит вам:
MockRoleService.IsUserInRole(...);
и получить ожидаемый вызов функции.
Я думаю, что это не то, что вы ищете. Вы, скорее всего, имеете некоторый звонок где-то в вашем коде, как первый, и вы надеетесь, что, используя издевающийся инструмент для создания Mockroleservice, вы бы вводили этот новый «тип» вместо старого. К сожалению, это не то, как это работает с статикой.
Инструмент издевательства создаст экземпляр издевался типа и введет, что на месте вызова для построения реального типа. Вызов к статическому методу пропускает все это.
Как упоминалось о Aaronous, вы, вероятно, должны сделать этот метод нормальным методом экземпляра. Это позволило бы правильно инъекционно инъекционно вводить услуги Mock Mock, позвольте вам переместить объявление метода в свой интерфейс IrolesserService и переопределить его в свою реализацию Mockrozeervice. Затем в коде, где вы «получаете» 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;
}
}