anything like pointers in c#?

232 Views Asked by At

I'm new to c# (& coding in general) and i can't find anything pointer equivalent.
When i searched google i got something like safe/unsafe but that's not what i needed.

Like in c++ if you had a pointer and it pointed towards some value, the change in the pointer would cause change in the original variable. Is there anything of such in c#?
example-

static class universal
{
   public static int a = 10;
}

class class_a
{
   public void change1()
   {
      universal.a--;
   }
}

class class_b
{
   public void change2()
   {
      some_keyword temp = universal.a; //change in temp gives change in a
      temp-= 5; //the purpose of temp is to NOT have to write universal.a each time
   }
}

...

static void Main(string[] args)
{
   class_b B = new class_b();
   class_a A = new class_a();
   A.change1();
   Console.WriteLine(universal.a);//it will print 9

   B.change2();
   Console.WriteLine(universal.a);//it will print 4
   Console.ReadKey();
}

Edit- thank you @Sweeper i got the answer i had to use ref int temp = ref universal.a;

5

There are 5 best solutions below

6
On BEST ANSWER

If you don't want unsafe code, I can think of two options.

Wrapper object

You can create a class like this, that wraps an int:

public class IntWrapper {
    public int Value { get; set; }
}

Then change a's type to be this class:

static class Universal
{
   public static IntWrapper a = new IntWrapper { Value = 10 };
}

class class_a
{
   public void change1()
   {
      universal.a.Value--;
   }
}

class class_b
{
   public void change2()
   {
      Universal temp = universal.a; //change in temp gives change in a
      temp.Value -= 5;
   }
}

This works because classes are reference types, and a holds a reference (similar to a pointer) to a IntWrapper object. = copies the reference to temp, without creating a new object. Both temp and a refers to the same object.

ref locals

This is a simpler way, but it is only for local variables. You can't use this for a field for example.

public void change2()
{
    ref int temp = ref universal.a; //change in temp gives change in a
    temp -= 5;
}
1
On

C# has references which are very similar to pointers. If a and b are both references to the same object, a change in a will also be seen in b.

For example, in:

class X {
    public int val;
}

void Main()
{
    var a = new X();
    var b = a;
    a.val = 6;
    Console.WriteLine(b.val);
}

6 will be written.

If you change the declaration of X from class to struct, then a and b will no longer be references, and 0 will be written.

0
On

In some cases (when an optimization is very needed) you can use almost C-like pointers. You can only do that by explicitly specifying you are aware of the risk by placing your code in unsafe scope:

unsafe
{
    int number = 777;
    int* ptr = &number;

    Console.WriteLine($"Data that pointer points to is: {number} ");
    Console.WriteLine($"Address that pointer holds: {(int)ptr}");
}

The unsafe context allows you to use pointers directly. Please note that by default this option is turned off from your project. To test this you would need to right-click on project>Properties>Build - Allow unsafe code

0
On

Like this?

using System;

namespace Demo
{
    class Program
    {
        static void Main()
        {
            var test = new class_a();
            test.change1();
            Console.WriteLine(universal.a); // Prints 18
        }
    }

    static class universal
    {
        public static int a = 10;
    }

    class class_a
    {
        public void change1()
        {
            ref int x = ref universal.a;

            ++x;
            ++x;
            ++x;
            x += 5;
        }
    }
}

[EDIT: I noticed that this is the same as the last part of Sweeper's answer, but I'll leave this here since it focusses just on that solution.]

3
On

In c# Pass By Reference is used instead of pointers, Here's the corrected code

static class universal
{
   public static int a = 10;
}

class class_a
{
   public void change1()
   {
      universal.a--;
   }
}

class class_b
{
   public void change2(ref int val)//use ref keyword for reference
   {
       int temp = val; //change in temp gives change in a
       val -= 5;
   }
}

static void Main(string[] args)
{
   class_b B = new class_b();
   class_a A = new class_a();
   A.change1();
   Console.WriteLine(universal.a);//it will print 9

   B.change2(ref universal.a); //pass value by reference using ref keyword
   Console.WriteLine(universal.a);//it will print 4
   Console.ReadKey();
}