3

私は次の配列を持っています:

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

そして次のような2番目の要素への参照:

int rr = myArray[1];

私は次のようなものが欲しい: rr = 500

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

私はあなたたちが私の考えを理解したことを願っています、私は上記の例のようにPythonでこれを簡単に行うことができます。だから
C#でこれを行う方法

4

6 に答える 6

5

私の解決策は、おそらくarr[1]バッキングプロパティとしてプロパティを作成することです

何かのようなもの:

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

rr=500;同じになりますarr[1]=500;

于 2012-09-09T11:11:22.787 に答える
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]);
    }
}
于 2012-09-09T11:07:24.530 に答える
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#をコーディングするときは、メモリアドレスシャッフルよりも高いレベルでコードを最適化しようとします。そのレベルで本当に最適化する必要がある場合は、C++でコードを記述してください。そのコードをdllとしてインポートすると、問題が十分に分離され、開発を試してみるのを忘れないでください!)

于 2012-09-09T11:47:23.167 に答える
1

単にmyArray[1] = 500!配列内の特定の整数への参照が特に必要な場合は、NahumLitvinが提案したようにプロパティを使用できます。

于 2012-09-09T11:13:49.780 に答える
1

@desanswerは私の興味を呼び起こしました。だから私は彼の解決策を試しました、そしてそれは期待通りに機能します:

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

オプションでコンパイルする必要があり/unsafeます。

これにより問題が発生する可能性があります。
したがって、このソリューションはお勧めしません

于 2012-09-09T11:24:22.797 に答える
1

必要なのは基本的に変数へのポインタです。int「値型」(またはのような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

はい、それは非常に複雑ですが、安全でないコードなしでもっと簡単にできるとは思えません。これ以上説明しなくてすみません。コメントですべての質問に答えます。

于 2012-09-10T12:10:23.873 に答える