1

I know that interfaces cannot contain operators, but is there a way I can require / tell the compiler that the + and / operators will be implemented by a certain class?

I want to do something like this:

public class AutoAverage<T> where T:(overloads + and /)
{
  private List<T> history ;  // 10-20 values

  public T NextAvg( T newValue )
  {
    // implementation wants to push newValue
    // into history, then sum
    // values in history and return an average
  }
}
1
  • 2
    That's a frequently requested feature. Making it work would require significant work in the CLR, but it is certainly on their radar. It's a possible feature for hypothetical future versions, but no promises. Commented Jun 13, 2009 at 5:25

5 Answers 5

3

Unfortunately, that isn't currently possible in C#.

Sign up to request clarification or add additional context in comments.

Comments

3

In cases like this, sometimes I will pass lambdas to the constructor:

public class AutoAverage<T>
{
    public AutoAverage(Func<T, T, T> sum, Func<T, T, T> divide) { ...

And in usage:

var autoAverage = new AutoAverage((x, y) => x + y, (x, y) => x / y);
// ... use it ...

It's a bit ugly when you're doing binary operations like this (I've more often used it for single-argument functions, e.g. unit conversions), but it has the advantage of simplicity.

Whether that's a good solution in your case will depend, among other things, on how often you construct AutoAverage. If you only create it one or two places (for each T), then passing the lambdas wouldn't be that bad. If you construct it a whole bunch of places, the lambdas would be duplicated too much for comfort.

Comments

2

You might be able to implement something close, using an interface as described in Marc Gravell's answer here: Solution for overloaded operator constraint in .NET generics

Comments

1

I'd try something like this:

interface ISumT<T>
{
  /// <summary>
  /// the sum method adds rhs to this and returns the result
  /// </summary>
  /// <remark>
  /// use a interface (i.e. ISumT)
  /// with a method (i.e. sum)
  /// because "where" doesn't support operators
  /// </remark>
  T sum(T rhs);
}

public class AutoAverage<T> where T : ISumT<T>
{
  public T NextAvg( T newValue )
  {
    // can assume that T implements the sum method
  }
}

1 Comment

... it turns out that making classes that implement ISumT for all the primitives is actually kind of tedious!
1

MiscUtil has generic aggregate functions (Sum, Average, etc) built in, using .NET 3.5 to provide generic operator support at runtime.

Additionally, C# 4.0 makes this possible via dynamic (which supports operators), but the above approach is usually faster (less indirection).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.