假设我有一个初始化列表:List<double> o
我想执行以下操作:
int offset = 10;
for (int i = 0; i < o.Count; ++i){
o[i] = ApplyRamp(o[i]-offset)
}
其中ApplyRamp定义为:
public static void ApplyRamp(ref double x)
{
if (x < 0) x = 0;
}
但代码无法编译。为什么List<double>
的单个元素(即o[i]
)未被视为类型double
?
答案 0 :(得分:4)
这里有四个问题:
ref
以及参数o[i] - offset
被归类为值而不是变量,因此您无法通过引用传递o[i]
也会被归类为值,因为它是调用索引器的结果。如果o
是double[]
(即数组而不是列表),那么o[i]
将被归类为变量。void
方法的结果作为赋值运算符的右侧。 void
方法没有结果。您可以使用:
double temp = o[i] - offset;
ApplyRamp(ref temp);
// Do something with temp?
但事后不清楚你对temp
做了些什么。您是要修改o
吗?如果是这样,offset
会在哪里进来?那么为什么你会在这种情况下分配给o[i]
?
最后,我强烈建议您考虑让ApplyRamp
只使用常规的按值参数,然后返回结果。这将使其在大多数情况下更容易使用。我很少在ref
方法中充分利用void
参数。
类似于:
public static double ApplyRamp(double x)
{
return x < 0 ? 0 : x;
}
或者只使用Math.Max
:
public static double ApplyRamp(double x)
{
return Math.Max(x, 0);
}
答案 1 :(得分:2)
您无法将void
分配给任何变量,我认为您应该更改方法的签名:
public static double ApplyRamp(double x)
{
if (x < 0) return 0;
return x;
}
现在,您的方法将返回double并将此值分配给o[i]
元素。
当用作方法的返回类型时,void指定该方法不返回值。
显然你想在这里返回一个值。因为(正如我想的那样),您希望将x
调整为非负数。所以我认为更改代码以返回double是最好的方法。
答案 2 :(得分:0)
如果您只是希望获得具有相同值的列表,但对于小于offset
的值减少offset
或等于0,则可以使用LINQ Select
。
它会通过将计算函数应用于List<double>
数组中的每个项目来创建新的o
,然后将此List
分配回o
:
o = o.Select(x => x - offset < 0 ? 0 : x - offset).ToList();
或
o = o.Select(x => Math.Max(x - offset, 0)).ToList();