1

I have a generic interface for a mathematics library, something like this:

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

This enables me to create an IMaths<double>, IMaths<decimal>, etc. (although at first I only need the double version).

I'd like to set up code contracts. At present I've done this:

[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;
    }
}

This seems to work, but I'm rather surprised that it does (given that I'm specifying contracts on IMaths<double> rather than IMaths<T>).

I'm left wondering:

  1. Can I specify multiple contract classes on a generic interface, one for each specific type I want to use (e.g. have both [ContractClass(typeof(MathsDoubleContracts))] and [ContractClass(typeof(MathsDecimalContracts))] attributes on IMaths<T>)? Is this a sensible thing to do?
  2. Would I be better off not using generic interfaces at all (i.e. start with, say, IMathsDouble where all the functions are defined in terms of doubles, adding IMathsDecimal later)?
Matthew Strawbridge
  • 19,940
  • 10
  • 72
  • 93

2 Answers2

1

Q1

Can you bring an example please.

EDIT

No. It does not allow multiple. Ref here.

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

Note AllowMultiple = false.

Q2

Yes, although generics might provide some little benefit. Your interface is not really generic. I cannot use IMaths<File> for example. I actually answered a different but related question here.

You may add restrictions such as where T : ... but that also will not do since you have to limit to only int, double while you can only do where T : struct which is not the same thing. Here generics is mere a decoration and the abstraction of IMaths<T> cannot be used as it is (or can it? can depend on your code) and you need concrete classes or interfaces.

A sub-interface is a safe option here

interface IntMaths : IMaths<int>
{

}
Community
  • 1
  • 1
Aliostad
  • 80,612
  • 21
  • 160
  • 208
0

I'm kind of doing this by applying a contract to a generic interface, the contract type is then inferred at runtime.

My problem however is defining a base abstract interface in a "common code" assembly which applies to an object of type IService then inherit that for type specific implementations that i require.

however I don't have to specify a type specific implementation i could simply (through dependency injection) determine the contract and object type at runtime ...

Code contract inheritance

I think my issue is making it "portable"

Community
  • 1
  • 1
War
  • 8,539
  • 4
  • 46
  • 98