我有一个双精度数组?我想更新(设置(它们的一些值。但是看起来我不能这样做。我尝试直接执行此操作,然后经过一些研究尝试了以下内容,它也不会更新原始对象(在这种情况下t2
(。我错过了什么?如何更新数组中包含的基础对象?
using System;
public class Program
{
public static void tst(ref double? input, int mult)
{
Console.WriteLine(input);
input = input * mult;
Console.WriteLine(input);
}
public static void Main()
{
double? t1 = 1.1;
double? t2 = 2.1;
double? t3 = 3.1;
double?[] ta = { t1, t2, t3 };
// change value of t2
tst(ref ta[1], 33);
Console.WriteLine(t1);
Console.WriteLine(t2); // I want this to be 69.3, but it’s still 2.1
Console.WriteLine(t3);
}
}
原因如前所述,您拥有的数组是变量值的副本,而不是其内存位置的副本。
这是一个荒谬的例子,说明如何克服这个问题,并且还可以通过制作一系列指针(内存中指向您的值的地址(来帮助更好地了解正在发生的事情
-
要获取地址,我们可以使用以下
&
-
要再次获取该值,我们可以在
*
-
要键入我们的指针,我们可以使用以下
type*
-
(IntPtr)(double*)
只是为了显示地址
法典
public unsafe static void tst(double* input, int multi)
{
Console.WriteLine("Make sure everything looks fine");
Console.WriteLine($"Ptr: {(IntPtr)input}, Value: {*input}");
// overwrite the location its pointing to
*input *= multi;
Console.WriteLine($"Ptr: {(IntPtr)input}, Value: {*input}");
}
private unsafe static void Main(string[] args)
{
//Some numbers
double t1 = 10;
double t2 = 20;
double t3 = 30;
Console.WriteLine("Locations and values");
Console.WriteLine($"Ptr: {(IntPtr)(double*)&t1}, Value: {t1}");
Console.WriteLine($"Ptr: {(IntPtr)(double*)&t2}, Value: {t2}");
Console.WriteLine($"Ptr: {(IntPtr)(double*)&t3}, Value: {t3}");
// create an array that pointers to the memory location of my awesome numbers
double*[] ta = { &t1, &t2, &t3 };
// pass in the array an
tst(ta[1], 324);
Console.WriteLine("Double check the results");
Console.WriteLine($"Ptr: {(IntPtr)(double*)&t1}, Value: {t1}");
Console.WriteLine($"Ptr: {(IntPtr)(double*)&t2}, Value: {t2}");
Console.WriteLine($"Ptr: {(IntPtr)(double*)&t3}, Value: {t3}");
}
输出
Locations and values
Ptr: 5239124, Value: 10
Ptr: 5239116, Value: 20
Ptr: 5239108, Value: 30
Make sure everything looks fine
Ptr: 5239116, Value: 20
Ptr: 5239116, Value: 6480
Double check the results
Ptr: 5239124, Value: 10
Ptr: 5239116, Value: 6480
Ptr: 5239108, Value: 30
其他资源
指针转换(C# 编程指南(
指针类型(C# 编程指南(
指针表达式(C# 编程指南(
如何:获取指针变量的值(C# 编程指南(
如何:获取变量的地址(C# 编程指南(
如何使用指针访问数组元素(C# 编程指南(
不安全(C# 参考(
更新
可以使用索引器
好的,上下文是我有一个类(除其他外( 包含 12 双?代表一年中月份的属性。一些 业务逻辑在运行时确定要更新哪些 基于 12 个值的传入数组。所以我本来希望使用 数组来驱动此实现以更新其值, 而不是 12 个单独的测试和有条件更新块。–
public class SomeClass
{
public int P1 { get; set; }
public int P2 { get; set; }
public int P3 { get; set; }
public int P4 { get; set; }
public int P5 { get; set; }
public int this[int i]
{
get {
switch (i)
{
case 0: return P1;
case 1: return P2;
case 2: return P3;
case 4: return P5;
}
}
set
{
switch (i)
{
case 0: P1 = value; break;
case 1: P2 = value; break;
case 2: P3 = value; break;
case 4: P4 = value; break;
}
}
}
}
...
SomeClass[2] // access like an array
这一行:
double?[] ta = { t1, t2, t3 };
ta
是一个新的双精度数组,使用t1
、t2
、t3
值(不是它们的引用(。ta[1]
与t2
不同,只是具有相同的值。 因此,通过 ref 传递ta[1]
将更改ta[1]
值,但不会更改t2
值(仅其值已复制到ta
(。因此,如果您查看ta[1]
值,则应将其更改为69.3
在打印 Console.WriteLine 之前,您必须为 ta[2] 和 ta[3] 调用 tst 函数
tst(ref ta[1], 33);
tst(ref ta[2], 33);
tst(ref ta[3], 33);
Console.WriteLine(ta[1]);
Console.WriteLine(ta[2]);
Console.WriteLine(ta[3]);
Console.WriteLine 必须是 printta[i],因为它在 tst 函数中引用了值