0

I'm new to C#. The following code is how I would achieve what I want in C++. I have reasons that the struct needs to be a struct (and mutable).

What would the C# equivalent of the following code be?

struct SomeStruct {
    int a;
    int b;
};

class SomeClass {
public:
    SomeStruct& target;

public:
    SomeClass(SomeStruct &t) :
        target(t)
    {
    }
};

I want to be able to use instances of SomeClass to mutate the underlying struct. I have seen this question but in my case the target is a struct.

Community
  • 1
  • 1
Macca
  • 43
  • 1
  • 6
  • Possible duplicate of [Store a reference to an object](http://stackoverflow.com/questions/13293073/store-a-reference-to-an-object) – Some programmer dude Feb 02 '17 at 08:08
  • 2
    In C++, there is practically no difference between a class and a struct, which isn't true in C#. A mutable struct in C# is a Very Bad Idea™. – vgru Feb 02 '17 at 08:08

2 Answers2

4

This is not possible for struct fields. You can only get a reference to a boxed struct in C# (i.e. a separately allocated struct), and this practically cancels any benefits of using a struct in the first place.

Since structs are passed around by value (e.g. copied from function parameters into local variables), passing around pointers to struct fields would mean you would easily get pointers to out-of-scope data.

C# was deliberately designed to avoid stuff like this:

// not real C# code
void SomeMethod()
{
    SomeStruct *ptr = GetStructPointer();

    // <-- what does ptr point to at this point?
}

SomeStruct* GetStructPointer()
{
    SomeStruct local;
    return &local;
}
vgru
  • 49,838
  • 16
  • 120
  • 201
  • 2
    @Macca: Well, you *could* acquire a pointer to pretty much anything within an `unsafe` block or an `unsafe` method. You *could* pass actual pointers around, if all methods dealing with those are marked `unsafe`. Or cast to `IntPtr` to be able to pass to managed code, and essentially pass the equivalent of `void*`. With the added caveat that the pointer object (unless within scope) might get moved by the garbage collector at any moment. So the only safe (or, less unsafe) way to use `IntPtr` would to pair it with `Marshal.AllocHGlobal` to get a pinned part of the memory. – vgru Feb 02 '17 at 08:47
1

It would be ref SomeStruct t param. See MSDN documentation for the ref C# keyword https://msdn.microsoft.com/en-us/library/14akc2c7.aspx .

Andrew Sklyarevsky
  • 2,095
  • 14
  • 17