由于泛型问题,我遇到了一些严重的设计问题。也许有人有一些建议。

编辑:所以,我知道通常不会这样做,但是我已经完全更改了示例代码,因为我意识到原始的伪代码并不能真正解释我的问题。以下代码与我正在处理的真实示例非常相似。我希望我的问题会得到解决。我很抱歉,这有点冗长,但是根据我的经验,当您尝试构建更复杂的结构时,泛型问题通常会出现。所以:

class Program
    {
        static void Main(string[] args)
        {
            IConnector<IService> connector = ConnectorBuilderFactory.NewBuilder<IService>("someEndpoint").MakeReliable().GetConnector();
            connector.Connect();
        }
    }

    public interface IService : IConnectionMaintainable
    {
        void DoSomething();
    }

    public interface IConnectionMaintainable
    {
        DateTime GetServerTime();
    }

    public interface IConnector<T>
    {
        T Channel { get; }
        void Connect();
        void Disconnect();
    }

    public interface IConnectorBuilder<T>
    {
        IConnector<T> GetConnector();
        IConnectorBuilder<T> MakeReliable();
        // ...more connector-configuration methods
    }

    public class ChannelWatchDog<T> where T : IConnectionMaintainable
    {
        private IConnector<T> connector;

        public ChannelWatchDog(IConnector<T> connector /*various other parameters*/)
        {
            this.connector = connector;
        }

        // ...methods that use connector's Connect, Disconnect, and GetServerTime methods
    }

    public class Connector<T> : IConnector<T>
    {
        private T channel;

        public Connector(string endpoint)
        {
            // ...build channel
        }

        public T Channel
        {
            get { return channel; }
        }

        public void Connect()
        {
            // ...connect to server
        }

        public void Disconnect()
        {
            // ...disconnect from server
        }
    }

    public class ConnectorBuilder<T> : IConnectorBuilder<T>
    {
        private string endpoint;

        public ConnectorBuilder(string endpoint)
        {
            this.endpoint = endpoint;
        }

        public IConnector<T> GetConnector()
        {
            Connector<T> connector = new Connector<T>(endpoint);

            // If reliability was requested, build the ChannelWatchDog: Following line does not compile:
            // ChannelWatchDog<T> watchDog = new ChannelWatchDog<T>(connector);

            return connector;
        }

        public IConnectorBuilder<T> MakeReliable()
        {
            // save various parameters required to build the ChannelWatchDog
            return this;
        }
    }

    public static class ConnectorBuilderFactory
    {
        public static IConnectorBuilder<T> NewBuilder<T>(string endpoint)
        {
            return new ConnectorBuilder<T>(endpoint);
        }
    }

因此,首先,如果在ConnectorBuilder类中找到GetConnector方法,则将看到带注释的代码行,如果未注释,则该行将不编译。这条线是我的问题的本质。该问题从代码中可能很明显,但是无论如何我都会尝试解释一下:
  • 我有一个需要IConnector的内部类(ChannelWatchDog)。但不仅仅是任何一个IConnector(一个IConnector),因为除了非通用IConnector方法之外,它还需要IConnectionMaintainable接口(interface)中的GetServerTime方法。
  • 为了简化连接器的构造,我希望使用Expression Builder模式(IConnectionBuilder接口(interface))实现一个构造器。但是,我希望能够构造任何IConnector,而不仅仅是IConnector 。因此,我无法以与为ChannelWatchDog约束T相同的方式约束IConnectorBuilder中的T。缺少此约束,调用GetConnector时无法构建它。将约束添加到MakeReliable方法无济于事。

  • 因此,从本质上讲,我发布此问题的原因是我想做一些看似不可能的事情。我希望ChannelWatchDog和ConnectorBuilder类看起来像这样:
    public class ChannelWatchDog
        {
            private IConnector<IConnectionMaintainable> connector;
    
            public ChannelWatchDog(IConnector<IConnectionMaintainable> connector /*various other parameters*/)
            {
                this.connector = connector;
            }
    
            // ...methods that use connector's Connect, Disconnect, and GetServerTime methods
        }
    
        public class ConnectorBuilder<T> : IConnectorBuilder<T>
        {
            private string endpoint;
    
            public ConnectorBuilder(string endpoint)
            {
                this.endpoint = endpoint;
            }
    
            public IConnector<T> GetConnector()
            {
                Connector<T> connector = new Connector<T>(endpoint);
    
                // If reliability was requested, build the ChannelWatchDog: Following line does not compile:
                ChannelWatchDog watchDog = new ChannelWatchDog((IConnector<IConnectionMaintainable>)connector);
    
                return connector;
            }
    
            public IConnectorBuilder<TReliable> MakeReliable<TReliable>() where TReliable : T, IConnectionMaintainable
            {
                // save various parameters required to build the ChannelWatchDog
                return (IConnectorBuilder<TReliable>)this;
            }
        }
    

    但是,对IConnector的强制转换在运行时失败。

    因此,这比我原本打算的要冗长得多。如果您已经阅读了那么多书,那么您已经感谢我了:)
    欢迎任何想法,包括重组代码。

    顺便说一句,我自己还没有找到解决方案,所以我在工厂中创建了不同的ConnectorBuilder(在本例中为ReliableConnectorBuilder)和不同的工厂方法。但是我不太喜欢这种解决方案。

    编辑:只是为了澄清和重申:我不能限制IConnector或ConnectionBuilder,因为这些需要支持未实现IConnectionMaintainable接口(interface)的情况。

    最佳答案

    代码到界面了吗?

    GenericClass<IFoo> wrapper = new GenericClass<IFoo>(new FooImplementor());
    Acceptor acceptor = new Acceptor(wrapper);
    

    10-06 07:10