如何引用C#数组中的值

时间:2012-09-09 10:56:33

标签: c#

我有以下数组:

int[] myArray = {21,21,364,658,87};

和第二个元素的引用如下:

int rr = myArray[1];

我想要的东西:  rr = 500

Console.writeLine(myArray[1]);// ---> should print 500 !

我希望你们有我的想法,我可以像上面的例子一样在python中轻松完成。 所以
如何在C#中执行此操作

6 个答案:

答案 0 :(得分:5)

我的解决方案可能是创建属性,arr[1]作为其后备属性

类似的东西:

  public int rr
  {
    set{ arr[1] = value;}
    get{ return arr[1];}
  }

rr=500;将与arr[1]=500;

相同

答案 1 :(得分:4)

您可以使用以下内容:

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]);
    }
}

答案 2 :(得分:2)

执行此操作时:

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导入,那么你就有了很好的关注点,并且不要忘记测试驱动开发!)

答案 3 :(得分:1)

只需myArray[1] = 500!如果您特别想要引用数组中的特定整数,可以使用Nahum Litvin建议的属性。

答案 4 :(得分:1)

@des回答唤醒了我的兴趣。所以我尝试了他的解决方案,它按预期工作:

int[] numbers = new[] { 1, 2, 3 };
fixed (int* number = &numbers[0])
{
  *number = 10;
}
Console.WriteLine(String.Join(", ", numbers)); // Outputs "10, 2, 3"

您必须使用/unsafe选项进行编译。

我希望你看到这可能会带来一些问题 因此我不建议使用此解决方案

答案 5 :(得分:1)

你想要的是一个基本指向变量的指针。 很难解释“值类型”(如intstruct),引用和指针之间的区别。我只能推荐学习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

是的,这很复杂,但我怀疑没有不安全的代码可以做得更简单。对不起,我再也不解释了。我将在评论中回答所有问题。