Переопределите статический метод

Я расширяю новый класс путем наследования 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;
    }
}
39
задан Black 3 November 2017 в 17:37
поделиться

8 ответов

Делать следующие то, что позволит вам работать вокруг статического вызова. Если вы хотите использовать код, возьмите 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;
    }
}
19
ответ дан 27 November 2019 в 02:19
поделиться

Вы не можете переопределить статический метод. Статический метод не может быть виртуальным, поскольку оно не связано с экземпляром класса.

Метод «переопределения» в полученном классе на самом деле является новым методом, не связанным с одним, определенным в базовом классе (отсюда NEW ключевое слово).

39
ответ дан 27 November 2019 в 02:19
поделиться

Статический метод представляет логику, относящуюся к самому типу. После того, как вы наследуете от этого типа, статические методы родительского типа не могут быть применены. Что вы можете сделать, это следующее:

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;
    }
}
0
ответ дан 27 November 2019 в 02:19
поделиться

Вы не можете переопределить статический метод.

Если вы думаете об этом, это не имеет смысла; Для того, чтобы иметь виртуальную рассылку, вам нужен фактический экземпляр объекта для проверки.

Статический метод также не может реализовать интерфейс; Если этот класс реализует интерфейс IROLESSERVICE , то я бы утвердовал, что метод не должен быть статичным вообще. Это лучший дизайн, чтобы иметь метод экземпляра, поэтому вы можете поменять ваш Mockroleservice с реальной службой, когда вы будете готовы.

17
ответ дан 27 November 2019 в 02:19
поделиться

Вы не можете переопределить статический метод. Вы можете найти это Интересно прочитано.

11
ответ дан 27 November 2019 в 02:19
поделиться

Существует два способа сделать работу вашего Mock Object:

1: измените подпись вашего родительского объекта из RoLesservice в Irolesservice (при условии, что вы уже не используете интерфейс). Затем внедряйте издевательства в Irolesservice вместо RoLesservice.

public class MockRoleService : IRolesService
{
    public new static bool IsUserInRole(string username, string rolename)
    {
        return true;
    }
}
  1. Зависимость вводит объект ролей.

Публичный класс Mockrozeervice: RoLesservice {

public MockRoleService ()
{
     Roles = OverridenRolesObjectThatAlwaysReturnsTrue;
}

}

0
ответ дан 27 November 2019 в 02:19
поделиться

Для того, чтобы вызвать статический метод, вам понадобится прямая ссылка на тип:

RolesService.IsUserInRole(...);

, в этом случае, если вы хотите иметь возможность, и вызовите статическую статичку «производной» Метод, падение ключевого слова "New" позволит вам:

MockRoleService.IsUserInRole(...);

и получить ожидаемый вызов функции.

Я думаю, что это не то, что вы ищете. Вы, скорее всего, имеете некоторый звонок где-то в вашем коде, как первый, и вы надеетесь, что, используя издевающийся инструмент для создания Mockroleservice, вы бы вводили этот новый «тип» вместо старого. К сожалению, это не то, как это работает с статикой.

Инструмент издевательства создаст экземпляр издевался типа и введет, что на месте вызова для построения реального типа. Вызов к статическому методу пропускает все это.

Как упоминалось о Aaronous, вы, вероятно, должны сделать этот метод нормальным методом экземпляра. Это позволило бы правильно инъекционно инъекционно вводить услуги Mock Mock, позвольте вам переместить объявление метода в свой интерфейс IrolesserService и переопределить его в свою реализацию Mockrozeervice. Затем в коде, где вы «получаете» rolesservice, вы просто называете элемент экземпляра вместо статического.

IRolesService svc = MyServiceInjector.GetService<IRolesService>();
svc.IsUserInRole(...);
3
ответ дан 27 November 2019 в 02:19
поделиться

Как насчет чего-то вроде этого:

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;
    }
}
3
ответ дан 27 November 2019 в 02:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: