C #: используя тип "себя" в качестве общего параметра? - PullRequest
7 голосов
/ 05 июля 2010

Это может показаться немного странным, но мне действительно нужно создать обходной путь для очень сложной дуплексной обработки сообщений в C #, особенно для того, чтобы заставить других разработчиков соблюдать принцип DRY.

Так что я делаю, чтобы у вас был многотонный тип, который выглядит так:

internal sealed class SessionManager<T> where T : DuplexServiceBase

, что совсем не проблема - пока что.

Однако, как только я хочу, чтобы службы (я собираюсь использовать один экземпляр на сеанс) регистрировались в SessionManager, начинаются хлопоты:

internal abstract class DuplexServiceBase : MessageDispatcherBase<Action>

(MessageDispatcherBase - мой класс, который создает поток и асинхронно отправляет сообщения).

Я хочу иметь метод, который выглядит следующим образом:

    protected void ProcessInboundMessage()
    {
        // Connect
        SessionManager<self>.Current.Connect(this);
    }

... но проблема в том, как бы мне добраться до "я"?

Мне действительно нужны отдельные менеджеры сеансов для каждого класса обслуживания, потому что у них у всех есть свои собственные уведомления (в основном это очень раздражающий «NotifyAllClients» - метод, который заставляет нас хотеть вырвать свои собственные волосы в последние часы) и мне нужно лечиться отдельно.

У вас есть ЛЮБЫЕ идеи?

Я не хочу использовать «AsyncPattern = true», кстати ... это потребует от меня отказа от безопасности типов, принудительного соблюдения контракта (это приведет к очень плохому злоупотреблению системой связи, которую я настраиваю здесь) и потребовало бы отказаться от СУХОГО принципа, было бы много повторяющегося кода повсюду, и это то, на что я серьезно нахмурился.

Edit:

Я нашел самое лучшее решение, благодаря ответам здесь - это МЕТОД РАСШИРЕНИЯ, хе-хе ...

    public static SessionManager<T> GetSessionManager<T>(this T sessionObject) 
        where T : DuplexServiceBase
    {
        return SessionManager<T>.Current;
    }

Я могу использовать это так:

GetSessionManager().Connect(this);

Миссия выполнена. : -D

Этот метод (принадлежит DuplexServiceBase) дает мне менеджер сеансов, с которым я хочу работать. Отлично! : -)

Ответы [ 2 ]

15 голосов
/ 05 июля 2010

Я бы написал вспомогательный метод:

static class SessionManager { // non-generic!
    static void Connect<T>(T item) where T : DuplexServiceBase {
        SessionManager<T>.Current.Connect(item);
    }
}

и используйте SessionManager.Connect(this), который вычислит это автоматически через вывод общего типа.

3 голосов
/ 05 июля 2010

Вы можете заключить вызов в универсальный метод, тем самым воспользовавшись выводом типа компилятора:

private static void ConnectSessionManager<T>(T service)
{
     SessionManager<T>.Current.Connect(service)
}

protected void ProcessInboundMessage()
{
    // Connect
    ConnectSessionManager(this);
}
...