[英]C# - Adding named variables to an array and changing their original values (not copies!)
I have four named variables:我有四个命名变量:
float smoothPlusError = smoothAngle + angleError;
float smoothMinusError = smoothAngle - angleError;
float smoothMinus90 = smoothAngle - 90;
float smoothPlus90 = smoothAngle + 90;
I need to check if each of these variables is above or below a certain threshold and then adjust accordingly.我需要检查这些变量中的每一个是否高于或低于某个阈值,然后进行相应调整。 To avoid repeating the same code four times, I am trying to do this in a loop as follows:为了避免重复相同的代码四次,我试图在一个循环中执行此操作,如下所示:
float[] angles = { smoothPlusError, smoothMinusError, smoothMinus90, smoothPlus90 };
for (int i = 0; i < angles.Length; i++)
{
if (angles[i] > 360)
angles[i] -= 360;
else if (angles[i] < 0)
angles[i] += 360;
}
The problem with this approach is that the array creates copies of the named variables and updating the values in the array does not update the original named variables.这种方法的问题是数组创建了命名变量的副本,并且更新数组中的值不会更新原始的命名变量。
Please advise how I can pass named variables to an array and update their original values?请告知我如何将命名变量传递给数组并更新它们的原始值?
You can't with value types (and float
is one).您不能使用值类型(而float
就是其中之一)。 Value type variables hold the value directly (not a reference to where the value is), so, except for one case (passing a ref
parameter to a method), it's not possible in C# to have two value-typed variables to point to the same position in memory.值类型变量直接保存值(不是对值所在位置的引用),因此,除了一种情况(将ref
参数传递给方法),在 C# 中不可能有两个值类型变量指向memory 中的 position 相同。
So you either use a method (and use ref
), or create a reference type (a class with a float
property or field)因此,您要么使用方法(并使用ref
),要么创建引用类型(具有float
属性或字段的 class)
You could put the float into an object and then change it there.您可以将浮动放入 object 中,然后在此处更改。 I would not recommend boxing and unboxing without a user defined type.我不建议在没有用户定义类型的情况下装箱和拆箱。
class AngleRef
{
internal AngleRef(float angle) {this.angle=angle;}
internal float angle;
}
public void Main()
{
float smoothAngle = 6;
float angleError = 2;
var smoothPlusError = new AngleRef(smoothAngle + angleError);
var smoothMinusError = new AngleRef(smoothAngle - angleError);
var smoothMinus90 = new AngleRef(smoothAngle - 90);
var smoothPlus90 = new AngleRef(smoothAngle + 90);
AngleRef[] angles = { smoothPlusError, smoothMinusError, smoothMinus90, smoothPlus90 };
for (int i = 0; i < angles.Length; i++)
{
if (angles[i].angle > 360)
angles[i].angle -= 360;
else if (angles[i].angle < 0)
angles[i].angle += 360;
}
}
Please advise how I can pass named variables to an array and update their original values?请告知我如何将命名变量传递给数组并更新它们的原始值?
It can't be done with value types, though I suppose it depends on whether you'll accept the fudge of turning the value types into reference types.值类型无法做到这一点,尽管我认为这取决于您是否会接受将值类型转换为引用类型的骗局。 One such fudge is to put things in single element arrays:一种这样的软糖是将东西放入单个元素 arrays 中:
float[] smoothPlusError = new[]{smoothAngle + angleError};
float[] smoothMinusError = new[]{smoothAngle - angleError};
float[] smoothMinus90 = new[]{smoothAngle - 90};
float[] smoothPlus90 = new[]{smoothAngle + 90};
float[][] angles = { smoothPlusError, smoothMinusError, smoothMinus90, smoothPlus90 };
for (int i = 0; i < angles.Length; i++)
{
if (angles[i][0] > 360)
angles[i][0] -= 360;
else if (angles[i][0] < 0)
angles[i][0] += 360;
}
[0]
basically then "becomes part of the variable name" everywhere you go: [0]
基本上然后在 go 的任何地方“成为变量名的一部分”:
Console.WriteLine(smoothPlusError[0]);
^^^^^^^^^^^^^^^^^^
Consider it the entire name
It's a seldom used but occasionally handy trick if you want to get value types to behave referency without declaring a dedicated ref type如果您想在不声明专用 ref 类型的情况下让值类型表现引用,这是一个很少使用但偶尔会很方便的技巧
The other thing I mentioned in the comments is potentially more useful:我在评论中提到的另一件事可能更有用:
public class SomeFloats{
private float[] angles = new float[4];
public float SmoothPlusError { get => angles[0]; set => angles[0] = value; }
public float SmoothMinusError { get => angles[1]; set => angles[1] = value; }
public float SmoothMinus90 { get => angles[2]; set => angles[2] = value; }
public float SmoothPlus90 { get => angles[3]; set => angles[3] = value; }
public void FixThem(){
for (int i = 0; i < angles.Length; i++)
{
if (angles[i] > 360)
angles[i] -= 360;
else if (angles[i] < 0)
angles[i] += 360;
}
}
}
You can still hence access these in an array-ey way internally (or externally if you want to expose it), but also refer to them by name in the code因此,您仍然可以在内部(或在外部,如果您想公开它)以数组方式访问它们,但也可以在代码中按名称引用它们
var sf = new SomeFloats(){ SmoothPlusError = 362 };
sf.FixThem();
Console.WriteLine(sf.SmoothPlusError); //2
Try like below尝试如下
float smoothPlusError = GetAngle(smoothAngle + angleError);
float smoothMinusError = GetAngle(smoothAngle - angleError);
float smoothMinus90 = GetAngle(smoothAngle - 90);
float smoothPlus90 = GetAngle(smoothAngle + 90);
private float GetAngle(float angle)
{
if (angle > 360)
return angle -= 360;
else if (angle < 0)
return angle += 360;
else
return angle;
}
EDIT: You can use an array with the ref keyword too:编辑:您也可以使用带有 ref 关键字的数组:
float smoothPlusError = smoothAngle + angleError;
float smoothMinusError = smoothAngle - angleError;
float smoothMinus90 = smoothAngle - 90;
float smoothPlus90 = smoothAngle + 90;
float[] angles = { smoothPlusError, smoothMinusError, smoothMinus90, smoothPlus90 };
for (int i = 0; i < 4; i++)
AdjustAngle(ref angles[i]);
private static void AdjustAngle(ref float angle)
{
if (angle > 360)
angle -= 360;
else if (angle < 0)
angle += 360;
}
You could create a simple class so it will be a reference type:您可以创建一个简单的 class 所以它将是一个引用类型:
class RefType<T>
{
T Value { get; set; }
public RefType(T value)
{
Value = value;
}
}
Then have your array:然后有你的数组:
RefType<float> smoothPlusError = new RefType<float>(smoothAngle + angleError);
RefType<float> smoothMinusError = new RefType<float>(smoothAngle - angleError);
RefType<float> smoothMinus90 = new RefType<float>(smoothAngle - 90);
RefType<float> smoothPlus90 = new RefType<float>(smoothAngle + 90);
RefType<float>[] angles = { smoothPlusError, smoothMinusError, smoothMinus90, smoothPlus90 };
Then loop with:然后循环:
foreach (var angle in angles)
{
if (angle.Value > 360)
angle.Value -= 360;
else if (angle.Value < 0)
angle.Value += 360;
}
An alternative solution would be to have the array as you main location for the angles and instead of variables storing the angles, they would instead be array indices:另一种解决方案是将数组作为角度的主要位置,而不是存储角度的变量,而是数组索引:
int smoothPlusError = 0;
int smoothMinusError = 1;
int smoothMinus90 = 2;
int smoothPlus90 = 3;
float[] angles = new float[]
{
smoothAngle + angleError,
smoothAngle - angleError,
smoothAngle - 90,
smoothAngle + 90
}
So you can use your existing loop to update the angles and refer to the specific variables as:因此,您可以使用现有循环来更新角度并将特定变量称为:
angles[smoothPlusError] = ...;
The best solution is @MekalaV's: refactor the code into a method.最好的解决方案是@MekalaV:将代码重构为方法。 But it seems you want to do it in-place, so you can use a ref
parameter.但似乎您想就地执行此操作,因此您可以使用ref
参数。
float smoothPlusError = smoothAngle + angleError;
float smoothMinusError = smoothAngle - angleError;
float smoothMinus90 = smoothAngle - 90;
float smoothPlus90 = smoothAngle + 90;
AdjustAngle(ref smoothPlusError);
AdjustAngle(ref smoothMinusError);
AdjustAngle(ref smoothMinus90);
AdjustAngle(ref smoothPlus90);
private void AdjustAngle(ref float angle)
{
if (angle > 360)
angle -= 360;
else if (angle < 0)
angle += 360;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.