C# 对参数dynamic[]的内容求和时出错

C# 对参数dynamic[]的内容求和时出错,c#,dynamic,parameters,C#,Dynamic,Parameters,我想创建一个函数,该函数将返回我传递的任意数量的参数的和(字符串的串联)。 下面的函数适用于字符串,但对其他数据类型(int、double…等)抛出错误。 我错过了什么? 错误: Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The call is ambiguous between the following methods or properties: 'System.Con

我想创建一个函数,该函数将返回我传递的任意数量的参数的和(字符串的串联)。
下面的函数适用于字符串,但对其他数据类型(int、double…等)抛出错误。
我错过了什么?

错误:

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 )
代码:

公共静态动态函数(params dynamic[]arr)
{
动态res=null;

对于(int i=0;i您当前的代码在
控制台中抛出异常。WriteLine(vv);
因为
vv
为空,调用变得不明确,与此代码的方式相同:

//错误CS0121:以下方法或属性之间的调用不明确:
//'Console.WriteLine(char[])和'Console.WriteLine(string)'
Console.WriteLine(空);
那么为什么在第二种情况下
vv
null呢?因为您从null开始,并将其添加到其中。我怀疑绑定器正在将
null
和非null整数转换为
int?
,然后使用提升的加法运算符执行加法。这种推理只是一种有根据的猜测,但结果肯定是null。(您可以通过对结果进行正常的空检查来检查。)

修复方法是以加法的“数组中的第一个元素”开始,而不是以null开始,并且仅当输入数组为null或空时才返回null(或者如果实际加法以null结束-如果null是数组中的一个元素,则可以这样做)。您还可以通过使用
对象
作为接收结果的局部变量的类型,而不是
动态
,来修复
控制台。WriteLine
即使在这种情况下也会导致问题。下面是一个修复所有这些问题的示例,以及使用更惯用的名称:

使用系统;
使用System.Linq;
公共课程
{
公共静态动态和(params dynamic[]arr)
{
如果(arr==null | | arr.Length==0)
{
返回null;
}
动态结果=arr[0];
foreach(arr.Skip(1)中的var项目)
{
结果+=项目;
}
返回结果;
}
静态void Main(字符串[]参数)
{
对象总和=总和(“我的”、“姓名”);
控制台写入线(总和);
总和=总和(5,6,7);
控制台写入线(总和);
Console.WriteLine(空);
}
}
输出:

myname
18

您当前的代码在控制台.WriteLine(vv);
中引发异常,因为
vv
为空,调用变得不明确,与此代码的方式相同:

//错误CS0121:以下方法或属性之间的调用不明确:
//'Console.WriteLine(char[])和'Console.WriteLine(string)'
Console.WriteLine(空);
那么为什么在第二种情况下
vv
null呢?因为您从null开始,并将其添加到其中。我怀疑绑定器正在将
null
和非null整数转换为
int?
,然后使用提升的加法运算符执行加法。这种推理只是一种有根据的猜测,但结果肯定是null。(您可以通过对结果进行正常的空检查来检查。)

修复方法是以加法的“数组中的第一个元素”开始,而不是以null开始,并且仅当输入数组为null或空时才返回null(或者如果实际加法以null结束-如果null是数组中的一个元素,则可以这样做)。您还可以通过使用
对象
作为接收结果的局部变量的类型,而不是
动态
,来修复
控制台。WriteLine
即使在这种情况下也会导致问题。下面是一个修复所有这些问题的示例,以及使用更惯用的名称:

使用系统;
使用System.Linq;
公共课程
{
公共静态动态和(params dynamic[]arr)
{
如果(arr==null | | arr.Length==0)
{
返回null;
}
动态结果=arr[0];
foreach(arr.Skip(1)中的var项目)
{
结果+=项目;
}
返回结果;
}
静态void Main(字符串[]参数)
{
对象总和=总和(“我的”、“姓名”);
控制台写入线(总和);
总和=总和(5,6,7);
控制台写入线(总和);
Console.WriteLine(空);
}
}
输出:

myname
18

欢迎来到StackOverflow!请阅读。特别是,你应该在你的问题中加入你看到的错误的详细信息。它抛出了什么错误?我猜你不能将
int
添加到
null
。你的方法不是抛出-
控制台。WriteLine
是,因为值为null,这是一个模棱两可的调用。Jonkeet已经给出了答案。请注意,如果没有
dynamic
,您也有
null+“我的”+“名字”
给出了
“我的名字”
,而
null+5+6+7
给出了
null
(当您不使用
动态
时,编译时类型为
int?
;当您使用
动态
时,
null
没有类型)。为避免异常,您可以使用
控制台.WriteLine((对象)vv);
。它将写入一个空字符串,后跟一个新行。欢迎使用StackOverflow!请阅读。特别是,您应该在问题中加入所看到错误的详细信息。它会引发什么错误?我猜您不能将
int
添加到
null
。您的方法不会引发-
控制台。WriteLine
是,因为值为null,这是一个模棱两可的调用。Jon Skeet已经给出了答案。请注意,如果没有
dynamic
,您也有
null+“我的”+“名字”
给出了
“我的名字”
,而
null+5+6+7
给出了
null
(对于编译时类型
int?
当您不使用
dynamic
时;当您使用
dynamic
时,
null
没有类型)。为了避免异常,您可以使用
Console.WriteLine((对象)vv);
。它将写入一个空字符串,后跟一个