简体   繁体   English

如何初始化通用局部变量?

[英]How to initialize generic local variable?

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. Sum必须是通用的,以允许它接受整数和浮点集。

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): 错误消息(大致而言):

  1. cannot convert int to T . 无法将int转换为T
  2. += is not available for T . +=不可用于T

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. C#不支持泛型类型的算术运算符。

Therefore, one option will be to Sum(del<int>, ..) , Sum(del<float>, ...) .. etc. 因此,一种选择是Sum(del<int>, ..)Sum(del<float>, ...)等。

Or, use dynamic : 或者,使用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. 对于您提供的示例,结果为30

You can use the generic Add() method defined here . 您可以使用此处定义的通用Add()方法。

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. 诀窍是将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);
    }
}

VERY similar to Simon Whitehead answer 非常类似于 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;
    }

this return also 30 这个回报也30

You need to use the default keyword, specifically: 您需要使用default关键字,特别是:

// 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. 我匆匆回答了标题中的问题,涉及在泛型之间执行添加操作的第二个问题,这个问题已在另一个StackOverflow问题中进行了介绍,因此我不会重复发表。 It involves using dynamic , which means you no longer have compile-time safety. 它涉及使用dynamic ,这意味着您不再具有编译时安全性。 Read the other question for more details. 阅读其他问题以获取更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM