如何初始化泛型局部变量
本文关键字:局部变量 泛型 初始化 | 更新日期: 2023-09-27 18:30:10
目标是创建一个简单的程序来计算预处理集的总和。Sum
必须是泛型的,才能同时接受整数集和浮点集。
以下代码未编译。你能告诉我怎么修吗?
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);
}
}
}
错误消息(粗略地说):
- 无法将
int
转换为T
+=
对T
不可用
忽略代码中的其他问题,你就无法完成你想要做的事情。C#不支持泛型类型上的算术运算符。
因此,一个选项将是Sum(del<int>, ..)
、Sum(del<float>, ...)
。。等
或者,使用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;
}
对于您提供的示例,此结果为30
。
您可以使用此处定义的通用Add()
方法。
诀窍是将s
的初始值作为类型T
传递到Sum()
方法中,而不是在函数内部初始化它。
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);
}
}
与Simon Whitehead回答非常相似
static T Sum<T>(del<T> df, dynamic data)
{
T s = default(T);
foreach (var x in data) s += df(x);
return s;
}
该返回值也是30
您需要使用default
关键字,特别是:
// was: T s = 0;
T s = default(T);
我匆忙地回答了标题中的问题,关于在泛型之间执行添加操作的次要问题,这已经在另一个StackOverflow问题中讨论过了,所以我不会重复发布。它涉及到使用dynamic
,这意味着您不再具有编译时安全性。阅读另一个问题了解更多详细信息。