Reputation: 3732
i have the following array :
int[] myArray = {21,21,364,658,87};
and a reference to the second element like so:
int rr = myArray[1];
i want something like :
rr = 500
Console.writeLine(myArray[1]);// ---> should print 500 !
i hope you guys got my idea , i can do this easily in python like the example above.
so
how to do this in C#
Upvotes: 3
Views: 280
Reputation: 5420
What you want is a basically pointer to a variable.
It's hard to explain the difference between "value type" (like int
or struct
), a reference and a pointer. I can only recommend learning C.
Here's solution that works, although it may need a lot of changes to your code.
//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;
}
}
now you can write:
//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!
please remember to never do:
rr = 600;
because this will actually create brand new myIntWrapper, that's not "connected" anywhere.
So remember:
rr.theValue = 500;//this changes the value somewhere
rr = myArray[3];//this changes where rr is "pointing" to
Yes, it's quite complicated but I doubt it can be done any simpler without unsafe code. I'm sorry for not explaining it more. I'll answer to all questions in comments.
Upvotes: 1
Reputation: 885
When you do this:
int[] myArray = {21,21,364,658,87};
int rr = myArray[1];
rr = 500;
You will only overwrite the value in rr, there is no way for you to get the actual memory address of an arrays inner elements, and thereby updating it.
My answer must therefore be:
myArray[1] = 500;
I'm trying to understand what you're trying to do, if you want to encapsulate your change in a function you could pass the reference on this way, but it's all about what you want to do with it:
public void Proc()
{
var ints = new [] { 1, 2, 3, 4 };
FunctionChangingByReference(ref ints[1]);
}
public void FunctionChangingByReference(ref int x)
{
x = 500;
}
In C# there are no pointers, only references.
(I'm lying a bit, you could use pointers if you create a unsafe context, but we don't do that in C#, and neither should you. When we code C++ we do, but that's C++, and we do it at a cost, we make the code a bit more fragile and error prone. When I code C# I try to optimize the code on a higher level than memory address shuffling. If you really need to optimize on that level you should write the code in C++ and import that code as a dll, then you have a good separation of concern, and don't forget to test drive the development!)
Upvotes: 2
Reputation: 4051
@des answer has awaken my interest. So I tried his solution and it works as expected:
int[] numbers = new[] { 1, 2, 3 };
fixed (int* number = &numbers[0])
{
*number = 10;
}
Console.WriteLine(String.Join(", ", numbers)); // Outputs "10, 2, 3"
You have to compile it with the /unsafe
option.
I hope you see that this may bring some problems.
Therefore I don't recommend this solution.
Upvotes: 1
Reputation: 816
Simply myArray[1] = 500
! You could use a property as Nahum Litvin has suggested if you specifically want a reference to a specific integer within the array.
Upvotes: 1
Reputation: 7197
my solution would probably be create property with arr[1]
as its backing property
something like:
public int rr
{
set{ arr[1] = value;}
get{ return arr[1];}
}
and than rr=500;
will be the same as arr[1]=500;
Upvotes: 5
Reputation: 6401
You could use something like this:
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]);
}
}
Upvotes: 4