hpjchobbes Ответов: 4

Расширения с вложенными именами


Я использую стороннюю библиотеку, которая имеет объект подключения под названием SessionManager. SessionManager позволяет создавать различные типы запросов для запроса, добавления или моддинга. Я пишу некоторые методы расширения, чтобы попытаться сделать кодирование быстрее, так как я склонен повторять код для многих проектов при использовании этого компонента. Вот обычный код, который я бы использовал для запроса списка cusotmers:
SessionManager manager = new SessionManager();
manager.OpenConnection(filename);
IMsgSetRequest MsgRequest = SessionManager.CreateMsgSetRequest();
ICustomerQuery query = MsgRequest.AppendCustomerQuery();
query.ActiveStatus.SetValue(ENActiveStatus.All);
IResponse response = SessionManager.DoRequests(MsgRequest);
if(response.StatusCode == 0) { return (ICustomerRetList)response.Detail; }
else { throw new Exception("Unknown error querying customers: " + response.StatusMessage; }

Я не знаю, возможно ли это с помощью расширений, но я хотел бы иметь возможность изменить свой код, чтобы сделать что-то вроде этого:
SessionManager manager = new SessionManager();
return manager.Customers.QueryAll();
Идея заключается в том, что я мог бы затем кодировать некоторые стандартные запросы, такие как
manager.Customers.QueryActive();
и
manager.Vendors.QueryAll();
Самая трудная часть, которую я не могу понять, - это часть между SessionManager и фактической функцией расширения для запроса. Не похоже, что вы можете сделать вложенный класс с расширениями.

Что я уже пробовал:

Я попытался создать статический класс внутри статического класса, но получил ошибку, что методы расширения должны быть в классе верхнего уровня. Я попробовал следующий код, но компилятор, похоже, не понял, что я пытаюсь сделать:
public static ICustomerRetList Customer.QueryAll(this SessionManager manager)

4 Ответов

Рейтинг:
2

Pete O'Hanlon

Вы не можете создавать свои методы расширения с помощью составных имен - на самом деле, вы не можете создать ни один метод, используя такое составное имя. Таким образом, хотя вы могли бы иметь CustomerQueryAll, вы не можете иметь Customer.QueryAll. Похоже, что вы действительно хотите иметь специализацию метода расширения, чтобы у вас было что-то вроде этого:

public static ICustomerRetList QueryAll(this Customer customer)
{
  // Do something here.
}
Таким образом, ваш менеджер кода.Покупатель.QueryAll () будет работать, потому что вы сейчас передаете клиента.


Рейтинг:
2

sachin.vishwa90

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


Richard Deeming

Если вы прочитаете ссылку, которую вы разместили, вы увидите, что ограничение применяется к классу, в котором определен метод расширения, НЕ класс, который расширяет метод.

Рейтинг:
1

Richard Deeming

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

Попробуйте что-нибудь вроде этого:

public static class MyExtensions
{
    public static CustomerWrapper Customer(this SessionManager session)
    {
        return new CustomerWrapper(session);
    }
}

public struct CustomerWrapper
{
    public CustomerWrapper(SessionManager session)
    {
        Session = session;
    }
    
    public SessionManager Session { get; }
    
    public ICustomerRetList QueryAll()
    {
        ...
    }
}

Вам просто нужно будет добавить скобки после Customer вызов:
SessionManager manager = new SessionManager();
return manager.Customer().QueryAll();


Рейтинг:
1

F-ES Sitecore

Вы можете сделать что-то вроде этого

public class CustomerManager
{
    private SessionManager sessionManager;

    public CustomerManager(SessionManager sessionManager)
    {
        this.sessionManager = sessionManager;
    }

    public ICustomerRetList QueryActive()
    {
        // use this.sessionManager to query active customers and return them
    }
}

public static class MyExtensions
{
    public static CustomerManager Customers(this SessionManager sessionManager)
    {
        return new CustomerManager(sessionManager);
    }
}


затем используйте его как

SessionManager manager = new SessionManager();

manager.Customers().QueryActive();


Вы можете сделать то же самое с поставщиками, поэтому у вас есть класс VendorManager.


Richard Deeming

Щелк!: D

F-ES Sitecore

Дураки редко отличаются: d

hpjchobbes

Таким образом, идея состоит в том, чтобы создать расширение для моего суб-обозначения, которое возвращает "менеджер" этого типа, а "менеджер" имеет только открытый конструктор, который принимает мой объект соединения и имеет функции для запроса. Похоже, это сработает.

С точки зрения "лучших практик" программирования, было бы это идеальным способом пойти, если бы вы имели дело с такого рода интерфейсом? Кажется странным, что для того, чтобы попасть сюда, нужно перепрыгнуть через несколько разных классов.

F-ES Sitecore

Я действительно предложил это решение только тогда, когда вы спрашивали о методах расширения. На самом деле я бы просто создал класс CustomerManager вручную, я бы не стал утруждать себя доступом к нему через расширение, так что вместо того, чтобы

см.Клиентам().QueryActive();

Я бы

CustomerManager cm = Новый CustomerManager(sm);
см.QueryActive();

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