代码之家  ›  专栏  ›  技术社区  ›  Turing Complete

C:使用“self”类型作为通用参数?

  •  7
  • Turing Complete  · 技术社区  · 14 年前

    这看起来有点奇怪,但我确实需要为C中非常复杂的双工通信处理创建一个变通方案,特别是强制其他开发人员遵守干燥原则。

    所以我要做的是有一个基于类型的多任务处理,看起来像这样:

    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”,顺便说一句…这将要求我放弃类型安全,强制遵守合同(这将导致我在这里建立的通信系统严重滥用),并要求放弃干燥原则,将有很多重复的代码遍布各地,这是我严重反对的。

    编辑:

    我找到了最好的解决方案,多亏了这里的答案——这是一种扩展方法,呵呵……

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

    我可以这样使用:

    GetSessionManager().Connect(this);
    

    任务完成。-D

    此方法(属于DuplexServiceBase)提供了我要使用的会话管理器。很完美!-)

    2 回复  |  直到 14 年前
        1
  •  15
  •   Marc Gravell    14 年前

    我会写一个助手方法:

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

    使用 SessionManager.Connect(this) 这将通过泛型类型推断自动解决。

        2
  •  3
  •   Tim Robinson    14 年前

    您可以用泛型方法包装调用,从而利用编译器的类型推断:

    private static void ConnectSessionManager<T>(T service)
    {
         SessionManager<T>.Current.Connect(service)
    }
    
    protected void ProcessInboundMessage()
    {
        // Connect
        ConnectSessionManager(this);
    }