我有以下数组:
int[] myArray = {21,21,364,658,87};
以及对第二个元素的引用,如下所示:
int rr = myArray[1];
我想要类似的东西:
rr = 500
Console.writeLine(myArray[1]);// ---> should print 500 !
我希望你们明白我的想法,我可以像上面的例子一样在 python 中轻松地做到这一点。那么
如何在 C# 中做到这一点
我有以下数组:
int[] myArray = {21,21,364,658,87};
以及对第二个元素的引用,如下所示:
int rr = myArray[1];
我想要类似的东西:
rr = 500
Console.writeLine(myArray[1]);// ---> should print 500 !
我希望你们明白我的想法,我可以像上面的例子一样在 python 中轻松地做到这一点。那么
如何在 C# 中做到这一点
我的解决方案可能是创建属性arr[1]
作为其支持属性
就像是:
public int rr
{
set{ arr[1] = value;}
get{ return arr[1];}
}
而比rr=500;
将与arr[1]=500;
你可以使用这样的东西:
public static class ArrayExtensions
{
public static Action<int> CreateSetter(this int[] array, int index)
{
return (value) => array[index] = value;
}
}
[TestFixture]
public class ArrayTest
{
[Test]
public void Test()
{
int[] myArray = {21,21,364,658,87};
Action<int> rr = myArray.CreateSetter(1);
rr(500);
Assert.AreEqual(500, myArray[1]);
}
}
当你这样做时:
int[] myArray = {21,21,364,658,87};
int rr = myArray[1];
rr = 500;
您只会覆盖 rr 中的值,您无法获取数组内部元素的实际内存地址,从而对其进行更新。
因此,我的回答必须是:
myArray[1] = 500;
我试图理解你想要做什么,如果你想将你的更改封装在一个函数中,你可以通过这种方式传递引用,但这完全取决于你想用它做什么:
public void Proc()
{
var ints = new [] { 1, 2, 3, 4 };
FunctionChangingByReference(ref ints[1]);
}
public void FunctionChangingByReference(ref int x)
{
x = 500;
}
在 C# 中没有指针,只有引用。
(我有点撒谎,如果你创建一个不安全的上下文,你可以使用指针,但我们不会在 C# 中这样做,你也不应该这样做。当我们编写 C++ 代码时,我们会这样做,但那是 C++,我们在成本,我们使代码更脆弱和容易出错。当我编写 C# 代码时,我尝试在比内存地址改组更高的级别上优化代码。如果你真的需要在那个级别上进行优化,你应该用 C++ 编写代码并将该代码作为 dll 导入,然后您就可以很好地分离关注点,并且不要忘记试驾开发!)
简直了myArray[1] = 500
!如果您特别想要引用数组中的特定整数,则可以使用 Nahum Litvin 建议的属性。
你想要的是一个基本上指向变量的指针。很难解释“值类型”(如int
or struct
)、引用和指针之间的区别。我只能推荐学习C。
这是可行的解决方案,尽管它可能需要对您的代码进行大量更改。
//a class that will hold an int inside
public class myIntWrapper
{
//this is the value wrapper holds
public int theValue;
//constructor taking the value
public myIntWrapper(int argument)
{
theValue = argument;
}
//operator to convert an int into brand-new myIntWrapper class
public static implicit operator myIntWrapper(int argument)
{
return new myIntWrapper(argument);
}
//operator to convert a myIntWrapper class into an int
public static implicit operator int(myIntWrapper wrapper)
{
return wrapper.theValue;
}
}
现在你可以写:
//create an array -
//setting values to every item in array works
//thanks to operator myIntWrapper(int argument)
myIntWrapper[] myArray = new myIntWrapper[5]{1,2,3,4,5};
//now take a "reference"
myIntWrapper rr = myArray[1];
//change the value
rr.theValue = 500;
//from now on myArray[1].theValue is 500;
//thanks to operator int(myIntWrapper wrapper)
//you can write:
int ss = rr;//it works!
请记住永远不要这样做:
rr = 600;
因为这实际上会创建全新的 myIntWrapper,它不会在任何地方“连接”。所以请记住:
rr.theValue = 500;//this changes the value somewhere
rr = myArray[3];//this changes where rr is "pointing" to
是的,这很复杂,但我怀疑如果没有不安全的代码,它可以做得更简单。我很抱歉没有更多地解释它。我会在评论中回答所有问题。
@des 的回答引起了我的兴趣。所以我尝试了他的解决方案,它按预期工作:
int[] numbers = new[] { 1, 2, 3 };
fixed (int* number = &numbers[0])
{
*number = 10;
}
Console.WriteLine(String.Join(", ", numbers)); // Outputs "10, 2, 3"
您必须使用该/unsafe
选项编译它。
我希望你看到这可能会带来一些问题。
因此我不推荐这个解决方案。