繁体   English   中英

我应该为通用接口使用类型化代码协定吗?

[英]Should I use typed code contracts for generic interfaces?

我有一个数学库的通用接口,如下所示:

[ContractClass(typeof(MathsDoubleContracts))]
public interface IMaths<T>
{
    T SomeFunction(T n);
}

这使我能够创建IMaths<double>IMaths<decimal>等(尽管起初我只需要double版本)。

我想建立代码合同。 目前,我已经做到了:

[ContractClassFor(typeof(IMaths<double>))]
public abstract class MathsDoubleContracts : IMaths<double>
{
    public double SomeFunction(double n)
    {
        // Always positive
        Contract.Ensures(0 <= Contract.Result<double>());

        return double.NaN;
    }
}

这似乎可行,但是我确实对此感到惊讶(考虑到我指定的是IMaths<double>而不是IMaths<T>上的合同)。

我只是想知道:

  1. 我可以在通用接口上指定多个合同类吗,针对我要使用的每种特定类型指定一个(例如,在IMaths<T>上同时具有[ContractClass(typeof(MathsDoubleContracts))][ContractClass(typeof(MathsDecimalContracts))]属性) ? 这是明智的做法吗?
  2. 我会完全不使用通用接口吗(例如,以IMathsDouble ,其中所有函数均以double形式定义,稍后再添加IMathsDecimal )?

Q1

你能举个例子吗?

编辑

不可以。不允许多个。 参考这里

AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]

注意AllowMultiple = false

Q2

是的,尽管泛型可能带来一点好处。 您的界面不是真正的通用。 例如,我不能使用IMaths<File> 实际上,我在这里回答了一个不同但相关的问题。

您可以添加限制,例如where T : ...但也不会这样做,因为您必须限制为intdouble而您只能在where T : struct做这件事,这是不一样的。 这里的泛型仅仅是一种修饰,不能直接使用IMaths<T>的抽象(或者可以吗?可以取决于您的代码),并且需要具体的类或接口。

子接口是一个安全的选择

interface IntMaths : IMaths<int>
{

}

我通过在通用接口上应用合同来做到这一点,然后在运行时推断合同类型。

但是,我的问题是在“通用代码”程序集中定义一个基本抽象接口,该接口适用于IService类型的对象,然后为我需要的特定于类型的实现继承该接口。

但是我不必指定特定于类型的实现,我可以简单地(通过依赖注入)在运行时确定协定和对象类型...

代码合同继承

我认为我的问题是使其变得“便携”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM