C# 如何初始化泛型局部变量?

C# 如何初始化泛型局部变量?,c#,generics,C#,Generics,目标是创建一个简单的程序来计算预处理集的总和。Sum必须是泛型的,以允许它同时接受整数和浮点集 以下代码不编译。你能告诉我怎么修吗 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { static class Program {

目标是创建一个简单的程序来计算预处理集的总和。
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);
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间控制台应用程序1
{
静态类程序
{
代表T del(T x);
静态T和(del df,IEnumerable数据)
{
ts=0;
foreach(数据中的var x)s+=df(x);
返回s;
}
静态void Main(字符串[]参数)
{
var数据=可枚举范围(1,4);
int sum=sum(x=>x*x,数据);
控制台写入线(总和);
}
}
}
错误消息(粗略地说):

  • 无法将
    int
    转换为
    T
  • +=
    不适用于
    T

  • 您需要使用
    default
    关键字,具体如下:

    // was: T s = 0;
    T s = default(T);
    

    我匆忙回答了标题中的问题,关于在泛型之间执行add操作的第二个问题,这个问题已经讨论过了,所以我不会重复发帖。它涉及到使用
    动态
    ,这意味着您不再具有编译时安全性。阅读另一个问题以了解更多详细信息。

    您需要使用
    default
    关键字,特别是:

    // was: T s = 0;
    T s = default(T);
    

    我匆忙回答了标题中的问题,关于在泛型之间执行add操作的第二个问题,这个问题已经讨论过了,所以我不会重复发帖。它涉及到使用
    动态
    ,这意味着您不再具有编译时安全性。阅读另一个问题以了解更多详细信息。

    忽略代码中的其他问题,您无法执行您试图执行的操作。C#不支持泛型类型上的算术运算符

    因此,一个选项将是
    Sum(del,…)
    Sum(del,…)
    。。等等

    或者,使用
    动态

    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;
    }
    
    代表T del(T x);
    静态T和(del df,IEnumerable数据)
    {
    动态s=默认值(T);
    foreach(数据中的var x)s+=df(x);
    返回s;
    }
    

    对于您提供的示例,此结果为
    30

    忽略代码中的其他问题,您无法执行您试图执行的操作。C#不支持泛型类型上的算术运算符

    因此,一个选项将是
    Sum(del,…)
    Sum(del,…)
    。。等等

    或者,使用
    动态

    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;
    }
    
    代表T del(T x);
    静态T和(del df,IEnumerable数据)
    {
    动态s=默认值(T);
    foreach(数据中的var x)s+=df(x);
    返回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);
        }
    }
    
    公共类程序
    {
    公共静态T添加(T a,T b)
    {
    var paramA=表达式参数(typeof(T),“a”);
    var paramB=表达式参数(typeof(T),“b”);
    var body=Expression.Add(paramA,paramB);
    var add=Expression.Lambda(body,paramA,paramB).Compile();
    返回添加(a,b);
    }
    公共代表T del(T x);
    //将变量s传递到函数中,而不是在函数中初始化它。
    公共静态T和(ts、del-df、IEnumerable数据)
    {
    返回数据。聚合(当前,x)=>Add(当前,df(x));
    }
    公共静态void Main(字符串[]args)
    {
    var数据=可枚举范围(1,4);
    int sum=sum(0,x=>x*x,数据);
    控制台写入线(总和);
    }
    }
    
    您可以使用定义的泛型
    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);
        }
    }
    
    公共类程序
    {
    公共静态T添加(T a,T b)
    {
    var paramA=表达式参数(typeof(T),“a”);
    var paramB=表达式参数(typeof(T),“b”);
    var body=Expression.Add(paramA,paramB);
    var add=Expression.Lambda(body,paramA,paramB).Compile();
    返回添加(a,b);
    }
    公共代表T del(T x);
    //将变量s传递到函数中,而不是在函数中初始化它。
    公共静态T和(ts、del-df、IEnumerable数据)
    {
    返回数据。聚合(当前,x)=>Add(当前,df(x));
    }
    公共静态void Main(字符串[]args)
    {
    var数据=可枚举范围(1,4);
    int sum=sum(0,x=>x*x,数据);
    控制台写入线(总和);
    }
    }
    
    与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;
        }
    
    static T Sum(del-df,动态数据)
    {
    ts=默认值(T);
    foreach(数据中的var x)s+=df(x);
    返回s;
    }
    

    这个返回值也与西蒙·怀特黑德的答案非常相似

        static T Sum<T>(del<T> df, dynamic data)
        {
            T s = default(T);
            foreach (var x in data) s += df(x);
            return s;
        }
    
    static T Sum(del-df,动态数据)
    {
    ts=默认值(T);
    foreach(数据中的var x)s+=df(x);
    返回s;
    }
    

    此返回值也为30

    ts=0应该是
    ts=默认值(T)-但是,您的另一个错误无法轻松解决。由于
    T
    可以是任何类(例如,
    object
    ),因此可能没有定义
    +
    运算符。这很难看,但您可以单独处理内置的数字类型,并查找+运算符
    ts=0应该是
    ts=默认值(T)-但是,您的另一个错误无法轻松解决。由于
    T
    可以是任何类(例如,
    对象
    ),因此可能没有定义
    +
    运算符。这很难看,但您可以处理