4

for example:

        int x = 1;
        int y = x;
        y = 3;
        Debug.WriteLine(x.ToString());

Is it any reference operator instead of "=" on line:3, to make the x equal to 3 , if i assign y =3 .

Cheung
  • 15,293
  • 19
  • 63
  • 93
  • No. There is not. This has come up before and I remember seeing a good response by Eric Lippert. –  Oct 21 '11 at 03:55
  • 3
    Can you explain why you would want something like that? Value types cannot do that. – Bala R Oct 21 '11 at 03:56
  • http://stackoverflow.com/questions/1420186/references-to-variables-in-c –  Oct 21 '11 at 04:02
  • 1
    http://stackoverflow.com/questions/3284767/can-i-use-a-reference-inside-a-c-sharp-function-like-c –  Oct 21 '11 at 04:08
  • 1
    @Bala R It has nothing to do with value vs. reference types. Question is about creating a reference [to a variable] (as is possible in C++), not about mutability [of objects]... granted there are generally "better approaches" to this problem. –  Oct 21 '11 at 04:15
  • thanks pst, your urls above is good. – Cheung Oct 21 '11 at 04:19

6 Answers6

10

I once wrote a prototype of a version of C# that had that feature; you could say:

int x = 123;
ref int y = ref x;

and now x and y would be aliases for the same variable.

We decided to not add the feature to the language; if you have a really awesome usage case I'd love to hear it.

You're not the first person to ask about this feature; see Can I use a reference inside a C# function like C++? for more details.

UPDATE: The feature will likely be in C# 7.

Community
  • 1
  • 1
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Here's an example, being able to make `x` to be `i` or `j` outside of the loop would've been much nicer. http://i.imgur.com/W12AMCN.png – shinzou Apr 16 '16 at 14:54
  • Looking for the _exact_ same feature I found this question (among many others alike). I have a situation which I consider very ordinary and I can't see a decent workaround to using a reference. What I want does not involve pointers, memory addresses or other "complicated" features of C++. I need a simple ("blind") reference (alias) more in the direction of `#define` from C++. I'm not either interested in passing/returning ref to/from functions, so there would be no stack related issues either. Take my situation: – mireazma Nov 02 '16 at 10:46
  • Situation: I have a few _int_ variables and at the press of a key (in a loop) I "assign" one to be the working variable from now on. Now all the work to follow (many functions) have to be on that particular variable (i.e. press another key to read/write to it). I can't see how to avoid _unnecessary/overhead_ code. C++ reference is absolutely perfect. Besides IMHO, just as passing by value for ref-types is allowed, the opposite should be as well. – mireazma Nov 02 '16 at 11:01
  • @mireazma: So then why not make a *delegate* which writes the variable? That then is your thing which represents access to the variable, and moreover, the lifetime of the variable is extended to the lifetime of the delegate instance. – Eric Lippert Nov 02 '16 at 13:51
  • See also [Proposal: Ref Returns and Locals](https://github.com/dotnet/roslyn/issues/118) . Note that it was closed as implemented on September 19th, and shows up on https://learn.microsoft.com/en-us/dotnet/articles/csharp/csharp-7 . So, this feature may be available in C# 7. – Brian Nov 02 '16 at 16:44
  • @Eric Lippert: just for the record - I'm not versed with delegates. I've tried all kinds of uses and I failed finding one to `1` trick a variable to refer to another or `2` force some methods to take a "dynamic" argument. The closest I could get was not using delegates but extracting code to an intermediary method accepting a `ref` arg. And then call all wanted methods from within this. Not really an issue but the mediating method is called from within an `if()` or `switch()` that would normally set the working variable. I need the method executed at later times, independent from any `if()`'s. – mireazma Nov 03 '16 at 20:47
  • @mireazma: Well basically it works like this: `int x = 123; Action set_x = new_x => { x = new_x; };` and now when you want to change the value of `x` you just say `set_x(4567);` and the value of `x` changes. But `set_x` is a value; you can put it in a field, in an array, return it, whatever, and it will keep `x` alive as long as it needs to. You can think of it as a boxed integer *with a setter*. – Eric Lippert Nov 03 '16 at 20:53
  • @Eric Lippert: I felt relieved for a moment then I recalled I have several _ints_ and I needed to _not_ know ahead of time which one to write (x, y etc.). So I was wrong when I previously mentioned C++ `#define` because I need the "alias" to be evaluated at runtime. Boxed integers would be of use just due to this. Nevertheless I'm grateful for the code and especially for your answer. – mireazma Nov 04 '16 at 09:33
  • @mireazma: Well then decide at runtime. `var set_something = foo ? set_x : set_y; ... set_something(123); ` – Eric Lippert Nov 04 '16 at 13:24
4

'int' is a value type and so copies the value on assignment, as you have discovered.

You could use pointers in the traditional C/C++ sense by using an 'unsafe' block but then the pointers are only usable inside that block which limits its use. If instead you want to access the value outside of an 'unsafe' block then you need to convert to using a reference instead.

Something like this...

var x = new Tuple<int>(1);
var y = x;
y.Item1 = 3;
Phil Wright
  • 22,580
  • 14
  • 83
  • 137
  • Note that this solution may not be practical if x was originally a field in a class. In such a situation, you can instead use [this code](http://stackoverflow.com/questions/2980463/how-do-i-assign-by-reference-to-a-class-field-in-c/2982037#2982037) provided by Eric Lippert in response to a similar question. – Brian Oct 21 '11 at 13:13
  • Note: `x` and `y` could be local variables for reference types, and the same truth applies. *Reassigning y does not affect x.* The bit about value types is irrelevant. – Anthony Pegram Oct 21 '11 at 14:05
3

This is not exactly what you're asking, but I thought it might be helpful. If you want a pointer alias inside a function, you can use the ref keyword like such:

public static void RefExample(ref int y)
{
    y = 3;
}

main()
{
    int x = 5;
    RefExample(ref x);
    Console.WriteLine(x); // prints 3
}
jb.
  • 9,921
  • 12
  • 54
  • 90
3

You can use pointers like in C

    int x = 1;
    unsafe
    {
        int* y = &x;
        *y = 3;
    }

    Debug.WriteLine(x.ToString());

(Note you have to compile with the unsafe flag)

John Alexiou
  • 28,472
  • 11
  • 77
  • 133
0

I wanted to comment Eric Lippert's answer, but new users cannot comments posts. So, I think I have such usage.

Take a look at this code:

private void SetGridColumns(ref RegistryKey targetKey, List<ColInfo> cols)
    {
        string targetKeyName = Path.GetFileName(targetKey.Name);
        m_grids.DeleteSubKeyTree(targetKeyName, false);
        targetKey.Close();
        targetKey = m_grids.CreateSubKey(targetKeyName);

//... }

    public void SetColumns(List<ColInfo> cols, bool youth)
    {
        RegistryKey key = youth ? m_youthGrid : m_mainGrid;
        SetGridColumns(ref key, cols);
    }

It should work like that: In SetColumns I call SetGridColumns with key depending on "youth" param. I would like my key to be first deleted and then recreated. m_mainGrid is of course member of a class. In this case, key is indeed deleted and recreated. But recreated is only "targetKey" in SetGridColumns, not my m_mainGrid.

So, the only thing I can do here is to make usage of pointers which is not preferred way in C#. If I could only do:

ref RegistryKey key = youth ? m_youthGrid : m_mainGrid;

everything should work fine.

Adam Jachocki
  • 1,897
  • 1
  • 12
  • 28
0

The only way to do this is to use "unsafe" code, and actually use pointers. Pointers cannot exist outside of unsafe code blocks in C#. You should then be able to use pointers the same way you do in C/C++

Check out this page for how to use "unsafe" code blocks.

xthexder
  • 1,555
  • 10
  • 22