Ошибка при суммировании содержимого параметров динамически [] - PullRequest
1 голос
/ 15 января 2020

Я хочу создать функцию, которая будет возвращать сумму (конкатенацию для строки) любого числа аргументов, которые я передаю.
Ниже функция хорошо работает со строкой, но выдает ошибку для других типов данных (int, double ... et c)
Чего мне не хватает?

Ошибка:

Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
  The call is ambiguous between the following methods or properties: 
   'System.Console.WriteLine(string, params object[])' and 
   'System.Console.WriteLine(char[])'
   at CallSite.Target(Closure , CallSite , Type , Object )

Код:

public static dynamic sumfunction(params dynamic[] arr)
{
    dynamic res=null;
    for(int i=0;i<arr.Length;i++)
    {
        res += arr[i];
    }

    return res;
}

static void Main(string[] args)
{
    dynamic vv=sumfunction("my","name");
    Console.WriteLine(vv);

    vv = sumfunction(5,6,7);
    Console.WriteLine(vv);
}

1 Ответ

3 голосов
/ 15 января 2020

Ваш текущий код вызывает исключение в Console.WriteLine(vv);, потому что vv имеет значение null, и вызов становится неоднозначным так же, как этот код:

// error CS0121: The call is ambiguous between the following methods or properties:
// 'Console.WriteLine(char[])' and 'Console.WriteLine(string)'
Console.WriteLine(null);

Так почему же vv нуль во втором случае? Потому что вы начали с нуля и добавили к нему. Я подозреваю, что механизм связывания преобразует как null, так и ненулевое целое число в int?, а затем выполняет сложение, используя оператор сложенного сложения. Это рассуждение является лишь обоснованным предположением, но, безусловно, результат будет нулевым. (Вы можете проверить это с помощью обычной проверки нуля на результат.)

Исправление состоит в том, чтобы начать с «первого элемента в массиве» для добавления, а не с нуля, и возвращать ноль только в том случае, если входной массив либо null, либо пусто (или если реальное добавление заканчивается нулем - что может сделать, если null является одним из элементов в массиве). Вы также можете исправить Console.WriteLine, вызывая проблему даже в этом случае, используя object в качестве типа локальной переменной, получающей результат, а не dynamic. Вот пример со всем, что исправлено, а также с использованием большего количества идиоматических c имен:

using System;
using System.Linq;

public class Program
{
    public static dynamic Sum(params dynamic[] arr)
    {
        if (arr == null || arr.Length == 0)
        {
            return null;
        }
        dynamic result = arr[0];
        foreach (var item in arr.Skip(1))
        {
            result += item;
        }

        return result;
    }

    static void Main(string[] args)
    {
        object sum = Sum("my", "name");
        Console.WriteLine(sum);

        sum = Sum(5, 6, 7);
        Console.WriteLine(sum);
        Console.WriteLine(null);
    }
}

Вывод:

myname
18
...