【问题标题】:How to translate this extension method to an interface method如何将此扩展方法转换为接口方法
【发布时间】:2016-10-11 19:51:06
【问题描述】:

假设我有以下扩展方法:

public static TContext Timeout<TContext>(this TContext context, TimeSpan timeout)
    where TContext : IContext
{
    // ...
}

这个扩展方法让我可以实现不变性并保留调用类型:

ITransactionalContext c = // ...;
c = c.Timeout(TimeSpan.FromSeconds(5));

但是,我怎样才能通过接口来实现呢?

例如,这将不一样:

public interface IContext
{
    IContext Timeout(TimeSpan timeout);
}

因为我的代码示例无法编译。

ITransactionalContext c = // ...;
c = c.Timeout(TimeSpan.FromSeconds(5)); // <-- An IContext is returned. Cannot assign to variable.

我可以将接口的上下文类型指定为通用参数:

public interface IContext
{

}

public interface IContext<TContext> : IContext
   where TContext : IContext
{
    TContext Timeout(TimeSpan timeout);
}

public interface ITransactionalContext : IContext<ITransactionalContext>
{

}

但这似乎一点也不好看。

另外,如果ITransactionalContext 需要更多参数怎么办:

public interface ITransactionalContext<TTransaction, TEntity>
    : IContext<ITransactionalContext<TTransaction, TEntity>>
{
}

这是一些泛型混乱。

有没有更简洁的方式来实现扩展方法实现的功能?

【问题讨论】:

  • “immutality”是“immutability”还是“immortality”的拼写错误?如果是后者,请立即提供完整的实现细节,谢谢。
  • Is there a cleaner way to achieve what the extension method achieves? 是的,使用扩展方法。您已经有了一个完全符合您需要的解决方案,为什么还要寻找另一个解决方案?
  • 添加到@Servy 所说的内容,您的解决方案看起来不错,虽然是一种扩展方法,但它使用的是泛型。以这种方式使用泛型是使用继承接口的替代方法。您说您的代码示例将不一样,但是如果您有派生类,您将获得适当的多态行为。
  • 我不明白你的问题。您可以在接口中声明该方法,就像您为扩展方法所做的那样:TContext Timeout&lt;TContext&gt;(DateTime timeout) where TContext : IContext;。如果您只想将扩展方法移动到接口中,为什么不这样做呢?

标签: c# .net generics interface


【解决方案1】:

使用扩展方法的解决方案是理想的,因为它依赖于编译器推断TContext 的能力。然而,它的主要缺点是它没有IContext 类提供它们自己的Timeout(TimeSpan) 方法实现。实际上,克隆过程的控制已脱离IContext 实现。

如果您想在IContext 实现中保留对克隆的控制,请组合使用接口方法和扩展方法,如下所示:

interface IContext {
    ... // Your methods
    IContext CloneWithTimeout(TimeSpan timeout);
}
...
public static TContext Timeout<TContext>(this TContext context, TimeSpan timeout)
    where TContext : IContext
{
    return (TContext)context.CloneWithTimeout(timeout);
}

您的用例继续编译,而生成新实例的过程完全由IContext 的实现控制。

【讨论】:

    猜你喜欢
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    相关资源
    最近更新 更多