-2

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;

  • [Value types](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types) and [Reference types](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types) – TheGeneral Dec 04 '20 at 08:53
  • _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#?_ - Look again! – TaW Dec 04 '20 at 10:06
  • `Pass By Reference` will solve your problem. – Salman Dec 04 '20 at 13:45

5 Answers5

2

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.

JoelFan
  • 37,465
  • 35
  • 132
  • 205
  • actually my entire point is to replace having to write "universal.a" every time and instead just have to write "temp"(single variable) and use that "temp" through out the function "change2" – Wired Differently Dec 04 '20 at 09:22
2

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;
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • well actually i don't want to have to write "universal.a" each time through out the function change2() instead just replace it with one variable name temp, having to write temp.a actually defeats the purpose ¯\_(ツ)_/¯ – Wired Differently Dec 04 '20 at 09:35
  • @WiredDifferently Oops. I copy pasted your code, and left the `.a` in there accidentally. You don't need `.a` if you use `ref` locals. You do need the `.Value`, but not the `.a` if you use a wrapper object though. – Sweeper Dec 04 '20 at 09:36
  • it's still giving error saying- "Cannot initialize a by-reference variable with a value" – Wired Differently Dec 04 '20 at 09:42
  • @WiredDifferently Don't forget the word `ref` before `universal.a` too. I forgot that, and now I have added it in. – Sweeper Dec 04 '20 at 09:43
  • Thank you very much i got the solution but just out of pure curiosity can this ref be used for all data types? like I'm working on some selenium code and i need to use IWebDriver in place of int (no need to answer this if you don't want to it's not exactly related to the Q i've posted) – Wired Differently Dec 04 '20 at 09:53
  • @WiredDifferently Read the docs I linked. It is much more reliable than my memory :) IIRC, yes. But note that `IWebDriver` is a reference type itself, so unless you are going to change the reference with `=`, you don't need ref at all. e.g. when you want to change its `Url`, you are not changing the variable itself, but rather mutating the object. In this case you don't need `ref`. If you are confused, go read the links that The General has provided in the comments of your question. – Sweeper Dec 04 '20 at 09:58
2

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

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
dimitar.d
  • 645
  • 1
  • 6
  • 18
2

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();
}
Techie Boy
  • 139
  • 1
  • 12
  • is there any way through which we don't have to use ref in the function parameter and instead directly assign temp inside the function? my entire purpose is to NOT have to write universal.a each time? and simply replace it with temp through out the function change2() but change in temp still induces change in universal.a – Wired Differently Dec 04 '20 at 09:27
  • 2
    you will find your answer here: https://stackoverflow.com/questions/2333574/is-there-pointer-in-c-sharp-like-c-is-it-safe#answer-2333614 – Techie Boy Dec 04 '20 at 09:36
  • Use `pass by reference`, You have already declared that the member as static, why don't you use it directly? – Agent Smith Dec 04 '20 at 09:39
0

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.]

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276