By Ref but inside a method.

R

Rene

So I am fooling around having some fun and I came up with the class below:

class Test
{
int m_One;
int m_Two;

public void DoIt(int intNumber)
{
ref int intToUpdate; // Won't compile.
if (intNumber == 1)
intToUpdate = m_One;
else
intToUpdate = m_Two;


intToUpdate = 123 * 456;
}
}

The basic idea in the example is that I am trying to get a reference to a
value type ("m_One" or "m_Two") depending on the value of the parameter.
Then once I have the reference (by ref) to the variable I assign a value to
the reference.

In the code I am expecting to change the value on either the "m_One" or
"m_Two" variables.

This won't work even if I was to use an object variable but I just used an
int for the sake of illustration.

Anyway, if I wanted to do something similar to this would it be possible?

And by the way, this example is purely for entertainment purposes, don't ask
why am I doing this because the answer is I am not doing it, just fooling
around :)

Thanks!
 
P

Peter Duniho

So I am fooling around having some fun and I came up with the class
below:

class Test
{
int m_One;
int m_Two;

public void DoIt(int intNumber)
{
ref int intToUpdate; // Won't compile.
if (intNumber == 1)
intToUpdate = m_One;
else
intToUpdate = m_Two;


intToUpdate = 123 * 456;
}
}

[...]
Anyway, if I wanted to do something similar to this would it be possible?

You certainly can accomplish similar behavior. Whether it meets your
standard for "similar", I don't know.

One obvious approach would be to wrap the "DoIt" method, like so:

public void DoItWrapper(int intNumber)
{
if (intNumber == 1)
DoIt(ref m_One);
else
DoIt(ref m_Two);
}

public void DoIt(ref int intToUpdate)
{
intToUpdate = 123 * 456;
}

Another obvious method would be to store those integers in an array
instead of making them individual fields. Then you just index the array
when you want to modify them.

A less-obvious method would be to wrap the fields themselves in a nested
class that has an indexer (my apologies if the syntax is slightly
off...didn't compile this):

class MyInts
{
public int m_One;
public int m_Two;

public int this[int iint]
{
get { return iint == 1 ? m_One : m_Two; }
set
{
if (iint == 1)
{
m_One = value;
}
else
{
m_Two = value;
}
}
}
}

then in your main class:

MyInts _myints;

public void DoIt(int intNumber)
{
_myints[intToUpdate] = 123 * 456;
}

while you can still access the individual fields as "_myints.m_One" and
"_myints.m_Two" (or make them properties and access them that way).

Yet another approach, perhaps the most bizarre (but IMHO still reasonable,
and I think probably even better than the above "indexer" approach), would
be to use an anonymous method to handle the assignment:

delegate void Assignment(int x);

public void DoIt(int intNumber)
{
Assignment assign;

if (intNumber == 1)
{
assign = delegate(int x) { m_One = x; };
}
else
{
assign = delegate(int x) { m_Two = x; };
}

assign(123 * 456);
}

Actually, the above is pretty clumsy in today's world of lambda
expressions. But I don't have that memorized yet. :) I think the
expression would look something like this: "x => m_One = x" and "x =>
m_Two = x". And I think there's an "Expression" type that would allowyou
to use it without having to declare the delegate type as I have. But I
can't tell you the specifics as to how to use that, off the top of my head.

So, in other words...yes, there are lots of different ways you could
accomplish what you're talking about. Heck, for that matter I think it's
possible you could pin the fields (or maybe the class instance) and use
unsafe code to do it the old-fashioned way (with & and *).

Hopefully, somewhere in there is something you find useful. :)

Pete
 
J

Jon Skeet [C# MVP]

Rene said:
So I am fooling around having some fun and I came up with the class below:

class Test
{
int m_One;
int m_Two;

public void DoIt(int intNumber)
{
ref int intToUpdate; // Won't compile.
if (intNumber == 1)
intToUpdate = m_One;
else
intToUpdate = m_Two;


intToUpdate = 123 * 456;
}
}

The basic idea in the example is that I am trying to get a reference to a
value type ("m_One" or "m_Two") depending on the value of the parameter.
Then once I have the reference (by ref) to the variable I assign a value to
the reference.

In the code I am expecting to change the value on either the "m_One" or
"m_Two" variables.

This won't work even if I was to use an object variable but I just used an
int for the sake of illustration.

Anyway, if I wanted to do something similar to this would it be possible?

And by the way, this example is purely for entertainment purposes, don't ask
why am I doing this because the answer is I am not doing it, just fooling
around :)

Okay, well if we're doing it for entertainment purposes, let's use a
delegate:

class Test
{
int m_One;
int m_Two;

public void DoIt(int intNumber)
{
Action<int> update;

if (intNumber == 1)
update = t => m_One = t;
else
update = t => m_Two = t;

update(123*456);
}
}
 
J

Jesse McGrew

So I am fooling around having some fun and I came up with the class below:

class Test
{
int m_One;
int m_Two;

public void DoIt(int intNumber)
{
ref int intToUpdate; // Won't compile.
if (intNumber == 1)
intToUpdate = m_One;
else
intToUpdate = m_Two;

intToUpdate = 123 * 456;
}

}

The basic idea in the example is that I am trying to get a reference to a
value type ("m_One" or "m_Two") depending on the value of the parameter.
Then once I have the reference (by ref) to the variable I assign a value to
the reference.

In the code I am expecting to change the value on either the "m_One" or
"m_Two" variables.

This won't work even if I was to use an object variable but I just used an
int for the sake of illustration.

Anyway, if I wanted to do something similar to this would it be possible?

And by the way, this example is purely for entertainment purposes, don't ask
why am I doing this because the answer is I am not doing it, just fooling
around :)

You can do it with TypedReference, if you don't mind using
undocumented keywords:

public void DoIt(int intNumber)
{
TypedReference intToUpdate;
if (intNumber == 1)
intToUpdate = __makeref(m_One);
else
intToUpdate = __makeref(m_Two);

__refvalue(intToUpdate, int) = 123 * 456;
}

Jesse
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top