gpt4 book ai didi

.net - 泛型类型转换

转载 作者:行者123 更新时间:2023-12-04 18:15:30 27 4
gpt4 key购买 nike

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

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

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 约束它一样约束 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)的情况。

    最佳答案

    接口(interface)代码?

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

    关于.net - 泛型类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4322697/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com