Reputation: 3519
The objective is to create a simple program that calculates the sum of pre-processed set. The Sum
must be generic to allow it accepts both integer and floating point set.
The following code does not compile. Could you tell me how to fix it?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
static class Program
{
delegate T del<T>(T x);
static T Sum<T>(del<T> df, IEnumerable<T> data)
{
T s = 0;
foreach (var x in data) s += df(x);
return s;
}
static void Main(string[] args)
{
var data = Enumerable.Range(1, 4);
int sum = Sum<int>(x => x * x, data);
Console.WriteLine(sum);
}
}
}
Error Messages (roughly speaking):
int
to T
.+=
is not available for T
.Upvotes: 1
Views: 1106
Reputation: 16884
You need to use the default
keyword, specifically:
// was: T s = 0;
T s = default(T);
I replied in haste to the question in the title, on the secondary issue of performing add operations between generics, this has been covered in another StackOverflow question, so I wont double post. It involves using dynamic
, which means you no longer have compile-time safety. Read the other question for more details.
Upvotes: 0
Reputation: 20140
VERY similar to Simon Whitehead answer
static T Sum<T>(del<T> df, dynamic data)
{
T s = default(T);
foreach (var x in data) s += df(x);
return s;
}
this return also 30
Upvotes: 0
Reputation: 54541
You can use the generic Add()
method defined here.
The trick is to pass the initial value of s
as the type T
into the Sum()
method instead of initializing it inside the function.
public class Program
{
public static T Add<T>(T a, T b)
{
var paramA = Expression.Parameter(typeof (T), "a");
var paramB = Expression.Parameter(typeof (T), "b");
var body = Expression.Add(paramA, paramB);
var add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
return add(a, b);
}
public delegate T del<T>(T x);
//pass the variable s into the function instead of initializing it inside the function.
public static T Sum<T>(T s, del<T> df, IEnumerable<T> data)
{
return data.Aggregate(s, (current, x) => Add(current, df(x)));
}
public static void Main(string[] args)
{
var data = Enumerable.Range(1, 4);
int sum = Sum(0, x => x * x, data);
Console.WriteLine(sum);
}
}
Upvotes: 1
Reputation: 65107
Ignoring the other issues with your code, you can't do what you're trying to do. C# does not support arithmetic operators on generic types.
Therefore, one option will be to Sum(del<int>, ..)
, Sum(del<float>, ...)
.. etc.
Or, use dynamic
:
delegate T del<T>(T x);
static T Sum<T>(del<T> df, IEnumerable<T> data)
{
dynamic s = default(T);
foreach (var x in data) s += df(x);
return s;
}
This results is 30
for your provided example.
Upvotes: 3