我只是想知道我是否错过了一些语法糖或微优化......
如果我调用一个需要 IEnumerable 值的方法,但我只有一个值,那么我将该单个值放入一个数组中。
例如:
var x = 1.23;
SquareAllTheNumbers(new[] { x });
private void SquareAllTheNumbers(IEnumerable<double> values)
{
foreach (var value in values)
{
Console.WriteLine(Math.Sqrt(value));
}
}
即使不需要,这也需要创建一个数组。看来我应该能够写出类似的东西:
var x = 1.23;
SquareAllTheNumbers(yield x);
有没有一种方法可以在不创建数组的情况下调用该函数?
[EDIT]感谢您的快速回复。因此,我了解到,有四种解决方案,如下所示以及过去的相同问题(将单个项目作为 IEnumerable 传递 https://stackoverflow.com/questions/1577822/passing-a-single-item-as-ienumerablet)。我当然喜欢额外的收益方法,并且不需要生成新的数组,但它更好吗?嗯,我一直想了解有关 Benchmark.NET 的更多信息,所以我决定测试这四个想法。这些都是:
- 制作一个数组(
new[] { x }
)
- 产量法
- 可枚举.重复
- 参数双[]
这些可以在下面的代码中更好地理解:
[Benchmark(Description = "Array Approach")]
public double ArrayApproach()
{
var x = 1.23;
return SumOfSquaredNumbers(new[] { x });
}
[Benchmark(Description = "Yield Method Approach")]
public double YieldMethodApproach()
{
return SumOfSquaredNumbers(Yield(x));
}
[Benchmark(Description = "Enumerable Repeat Approach")]
public double RepeatMethodApproach()
{
return SumOfSquaredNumbers(Enumerable.Repeat(x, 1));
}
[Benchmark(Description = "Params Approach")]
public double ParamsApproach()
{
return SumOfSquaredNumbers(x);
}
private double SumOfSquaredNumbers(IEnumerable<double> values)
{
var result = 0.0;
foreach (var value in values)
{
result = value * value;
}
return result;
}
private double SumOfSquaredNumbers(params double[] values)
{
var result = 0.0;
foreach (var value in values)
{
result = value * value;
}
return result;
}
public IEnumerable<T> Yield<T>(T item)
{
yield return item;
}
这是基准测试的结果:
| Method | Mean | Error | StdDev | Gen 0 | Allocated |
|----------------------------- |----------:|-----------:|----------:|-------:|----------:|
| 'Array Approach' | 6.970 ns | 10.7471 ns | 0.5891 ns | 0.0076 | 32 B |
| 'Yield Method Approach' | 30.256 ns | 21.7358 ns | 1.1914 ns | 0.0114 | 48 B |
| 'Enumerable Repeat Approach' | 30.058 ns | 32.9930 ns | 1.8085 ns | 0.0095 | 40 B |
| 'Params Approach' | 5.330 ns | 0.6169 ns | 0.0338 ns | 0.0077 | 32 B |
所以,看起来最好的方法就是创建一个新数组。第四个选项(使用params double[]
) 表现良好,但这有点超出了问题的范围,因为我的意思是该方法是“一成不变”的 - 例如,第 3 方 DLL 的一部分。