Home All Groups Group Topic Archive Search About

Assigning a reference to a variable

Author
26 Nov 2007 4:44 PM
Jon
If I have a structure, for example:

struct Settings{
  public string str;
  public double doub1, doub2;
  public int i1;
}

How do I assign the reference of i1 to a variable? I can easily do this by passing it as a ref int
to a function, but is there a way to do this without passing it to a function?

Author
26 Nov 2007 4:53 PM
Jon Skeet [C# MVP]
On Nov 26, 4:44 pm, "Jon" <.> wrote:
> If I have a structure, for example:
>
> struct Settings{
>   public string str;
>   public double doub1, doub2;
>   public int i1;
>
> }
>
> How do I assign the reference of i1 to a variable? I can easily do this by passing it as a ref int
> to a function, but is there a way to do this without passing it to a function?

No. If you want a type to behave like a reference type, you should
make it a reference type to start with.

Jon
Author
26 Nov 2007 5:39 PM
Tom Porterfield
Jon wrote:
> If I have a structure, for example:
>
> struct Settings{
>   public string str;
>   public double doub1, doub2;
>   public int i1;
> }
>
> How do I assign the reference of i1 to a variable? I can easily do this by passing it as a ref int
> to a function, but is there a way to do this without passing it to a function?

You can do it using unsafe code, but I wouldn't recommend that.  If you
use unsafe code, the syntax is very similar to C++.

Settings sets = new Settings();
sets.i1 = 5;
int *x = &sets.i1;
*x = 6;

Console.WriteLine(sets.i1.ToString());
--
Tom Porterfield
Author
27 Nov 2007 8:49 AM
Jon
Thanks for your replies Jon + Tom.

I'm from a C background, but I don't really want to use unsafe code.

"If you want a type to behave like a reference type, you should make it a reference type to start
with." How do I make an integer a reference type?

Jon


"Jon" <.> wrote in message news:OqsvruEMIHA.820@TK2MSFTNGP06.phx.gbl...
If I have a structure, for example:

struct Settings{
  public string str;
  public double doub1, doub2;
  public int i1;
}

How do I assign the reference of i1 to a variable? I can easily do this by passing it as a ref int
to a function, but is there a way to do this without passing it to a function?
Author
27 Nov 2007 9:03 AM
Marc Gravell
> "If you want a type to behave like a reference type, you should make it a reference type to start
> with." How do I make an integer a reference type?

You don't; you make Settings a reference type by changing "struct" to
"class". It is normally *very* rare to write a "struct" in .net, and
usually relates to discreet (but possibly compound) "values" - such as
a CompexInt32 or TimeRange.

> How do I assign the reference of i1 to a variable?

There is no such thing as a reference of i1; you could "box" it, but
that changes the meaning.

> I can easily do this by passing it as a ref int

Actually, this does something different again... can I recommend you
read the following? (one of Jon's pages)

http://www.pobox.com/~skeet/csharp/parameters.html

Marc
Author
27 Nov 2007 9:20 AM
Jon
Thanks Marc. I read Jon Skeet's page a few weeks ago and found it very helpful.

I think my problem is that my mind thinks in C, and it's having some problems adapting to C#.

I'm a bit nervous about changing the structs (I have quite a few) to classes, since it might break
something.

Am I right in saying that I can get a reference to an array inside a struct? If so, would having a
single-element array work?

struct Settings{
  public string str;
  public double doub1, doub2;
  public intRef[];
}

....

int[] int1 = new int[1];
intRef = int1;



"Marc Gravell" <marc.grav***@gmail.com> wrote in message
news:a83597b1-517a-48ed-8659-aedeb7bb7b3d@f3g2000hsg.googlegroups.com...
> "If you want a type to behave like a reference type, you should make it a reference type to start
> with." How do I make an integer a reference type?

You don't; you make Settings a reference type by changing "struct" to
"class". It is normally *very* rare to write a "struct" in .net, and
usually relates to discreet (but possibly compound) "values" - such as
a CompexInt32 or TimeRange.

> How do I assign the reference of i1 to a variable?

There is no such thing as a reference of i1; you could "box" it, but
that changes the meaning.

> I can easily do this by passing it as a ref int

Actually, this does something different again... can I recommend you
read the following? (one of Jon's pages)

http://www.pobox.com/~skeet/csharp/parameters.html

Marc
Author
27 Nov 2007 9:51 AM
Peter Duniho
On 2007-11-27 01:20:14 -0800, "Jon" <.> said:

> [...]
> I'm a bit nervous about changing the structs (I have quite a few) to
> classes, since it might break something.

Like what?

IMHO, on the balance it's more likely that switching to classes will
_fix_ more things than it breaks.  :)

> Am I right in saying that I can get a reference to an array inside a
> struct? If so, would having a single-element array work?

Yes.  But boy, what a hack.

It's hard to offer specific advice without specific information
regarding what you're trying to do here.  But my general rule of thumb
is: if you find yourself hacking around a perceived limitation in the
language, your first thought should be that you simply haven't adapted
to the language yet and your time would be better-spent figuring out
what the language-friendly way to solve your design issue is.

It's not a perfect rule of thumb, but it's served me very well over the years.

You haven't explained in any detail why it is you want to be able to
pass an integer variable by reference, but it's likely that whatever
the reason, you're just going to make things hard on yourself later by
not learning and accepting the normal way of doing things in C# now.

Pete
Author
28 Nov 2007 11:16 AM
Jon
Hi Peter

"Like what?" I don't actually know - I'm following the "if it ain't broke, don't fix it" philosophy
at the moment. I'm curious about your comment that switching to classes will fix more things than it
breaks. Are structs really that delicate?

"Yes.  But boy, what a hack." I agree.

"you simply haven't adapted to the language yet and your time would be better-spent figuring out
what the language-friendly way to solve your design issue is" I agree - see the extra details I've
given in my reply to Jeffrey's question.

Thanks for you help,

Jon


"Peter Duniho" <NpOeStPe***@NnOwSlPiAnMk.com> wrote in message
news:2007112701514843658-NpOeStPeAdM@NnOwSlPiAnMkcom...
On 2007-11-27 01:20:14 -0800, "Jon" <.> said:

> [...]
> I'm a bit nervous about changing the structs (I have quite a few) to
> classes, since it might break something.

Like what?

IMHO, on the balance it's more likely that switching to classes will
_fix_ more things than it breaks.  :)

> Am I right in saying that I can get a reference to an array inside a
> struct? If so, would having a single-element array work?

Yes.  But boy, what a hack.

It's hard to offer specific advice without specific information
regarding what you're trying to do here.  But my general rule of thumb
is: if you find yourself hacking around a perceived limitation in the
language, your first thought should be that you simply haven't adapted
to the language yet and your time would be better-spent figuring out
what the language-friendly way to solve your design issue is.

It's not a perfect rule of thumb, but it's served me very well over the years.

You haven't explained in any detail why it is you want to be able to
pass an integer variable by reference, but it's likely that whatever
the reason, you're just going to make things hard on yourself later by
not learning and accepting the normal way of doing things in C# now.

Pete
Author
28 Nov 2007 6:37 PM
Peter Duniho
On 2007-11-28 03:16:33 -0800, "Jon" <.> said:

> Hi Peter
>
> "Like what?" I don't actually know - I'm following the "if it ain't
> broke, don't fix it" philosophy at the moment. I'm curious about your
> comment that switching to classes will fix more things than it breaks.
> Are structs really that delicate?

It's not so much that they are delicate, but that they are in some ways
significantly different from classes, even as they look very similar. 
For a person just learning C#, it's possible that just as you find
yourself getting comfortable with the "reference-only" nature of
classes (something that's necessary for effective C# programming),
something specific about the value-type nature of structs will be
overlooked, resulting in a confusing bug.

This can especially problematic for someone experienced in C++
programming, where there's no real difference between a struct and a
class except for default accessibility.  In C#, structs and classes
fill very specific roles, different from each other.

I didn't mean to give the impression that structs are somehow a fragile
way to code.  They aren't.  It's just that they a different enough from
classes that it's not hard to get confused about how to use them,
especially for someone new to the language (and I'm not just saying
this in an abstract way...I was once new to the language myself, and I
still remember the process of figuring out the implications of the
difference between a value type and a reference type).

Pete
Author
28 Nov 2007 2:41 AM
Jeffrey Tan[MSFT]
Hi Jon,

Do you mind to tell me why you want to assign an integer reference to
another variable? What is the type of the another variable? Yes, in .Net
any array is reference type, however, I do not think your
solution/workaround is neat and may cause some other problems.

If you tell us the reason for the requirement, there may be a better
solution for it. Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
28 Nov 2007 11:04 AM
Jon
Hi Jeffrey,

Thanks for offering to help.

I have a variable that I would like to use as a reference to different variables within my struct.

My original example struct was too generalised to show this, and although the following is a
simplification of my real code, it is closer to a concise but complete example...


struct Settings{
  public int left, right, centre;
}

Settings set = new Settings();
int ref intRef ;  // ILLEGAL C# STATEMENT - note the use of "ref"
if(???) intRef = set.left;
else if(???) intRef = set.right;
else intRef = set.centre;

Then I would change the value that intRef points to.


From my C perspective, If I can do this with an array, it seems reasonable to me that I should be
allowed to do it with an int. I cannot do anything dangerous (eg increment a pointer which might
then point to something invalid).

To repliers who have suggested using a class rather than a struct, I'm not sure if this would
actually with my example, but maybe you can advise on this.

Jon


""Jeffrey Tan[MSFT]"" <je***@online.microsoft.com> wrote in message
news:LQ9DvgWMIHA.7908@TK2MSFTNGHUB02.phx.gbl...
Hi Jon,

Do you mind to tell me why you want to assign an integer reference to
another variable? What is the type of the another variable? Yes, in .Net
any array is reference type, however, I do not think your
solution/workaround is neat and may cause some other problems.

If you tell us the reason for the requirement, there may be a better
solution for it. Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
Author
28 Nov 2007 6:45 PM
Peter Duniho
Show quote
On 2007-11-28 03:04:23 -0800, "Jon" <.> said:

> Hi Jeffrey,
>
> Thanks for offering to help.
>
> I have a variable that I would like to use as a reference to different
> variables within my struct.
>
> My original example struct was too generalised to show this, and
> although the following is a
> simplification of my real code, it is closer to a concise but complete
> example...
>
>
> struct Settings{
>   public int left, right, centre;
> }
>
> Settings set = new Settings();
> int ref intRef ;  // ILLEGAL C# STATEMENT - note the use of "ref"
> if(???) intRef = set.left;
> else if(???) intRef = set.right;
> else intRef = set.centre;
>
> Then I would change the value that intRef points to.

I think the above is not a literal example of what you're trying to do.
After all, if the "int ref" were actually in the same method, it would
be simple enough to just set the field explicitly in the conditional:

    if (???)
        set.left = ...;
    else if (???)
        set.right = ...;
    else
        set.centre = ...;

So then the question is, what is the actual context here?  Why is it
that you have a conditional in one method, that then needs to be acted
upon somewhere else?  There _might_ be a better way to accomplish what
you're doing, but genuine specifics would be needed in order to answer
the question.

And for what it's worth, while I really like C#, the fact is that in
its simplicity (which I think is a good thing) it has left out some
kinds of things you could do in other languages (like C++).  Now and
then, you may actually run across something that simply can't be done
in the same way, and occasionally that means you need to write more
explicit code.

(I hesitate to mention reflection, which is the "back door" sort of way
to deal with some situations that are like this one; it would be
possible to obtain something that's essentially like a reference to the
property or field you're trying to set by using reflection, but IMHO
reflection should be avoided unless there's really literally no other
way to implement the behavior you want, which doesn't appear to be the
case here).

Pete
Author
29 Nov 2007 8:40 AM
Jon
Hi,

Thanks for your reply again Peter. *intRef will be used many times at various points, so a
simplified example is...


if(???) intRef = set.left;
else if(???) intRef = set.right;
else intRef = set.centre;

Use *intRef

Some general code

Use *intRef

Some general code

Use *intRef

etc


Jon


"Peter Duniho" <NpOeStPe***@NnOwSlPiAnMk.com> wrote in message
news:2007112810451475249-NpOeStPeAdM@NnOwSlPiAnMkcom...
On 2007-11-28 03:04:23 -0800, "Jon" <.> said:

I think the above is not a literal example of what you're trying to do.
After all, if the "int ref" were actually in the same method, it would
be simple enough to just set the field explicitly in the conditional:

    if (???)
        set.left = ...;
    else if (???)
        set.right = ...;
    else
        set.centre = ...;

So then the question is, what is the actual context here?  Why is it
that you have a conditional in one method, that then needs to be acted
upon somewhere else?  There _might_ be a better way to accomplish what
you're doing, but genuine specifics would be needed in order to answer
the question.

And for what it's worth, while I really like C#, the fact is that in
its simplicity (which I think is a good thing) it has left out some
kinds of things you could do in other languages (like C++).  Now and
then, you may actually run across something that simply can't be done
in the same way, and occasionally that means you need to write more
explicit code.

(I hesitate to mention reflection, which is the "back door" sort of way
to deal with some situations that are like this one; it would be
possible to obtain something that's essentially like a reference to the
property or field you're trying to set by using reflection, but IMHO
reflection should be avoided unless there's really literally no other
way to implement the behavior you want, which doesn't appear to be the
case here).

Pete
Author
29 Nov 2007 6:02 PM
Peter Duniho
On 2007-11-29 00:40:14 -0800, "Jon" <.> said:

> Thanks for your reply again Peter. *intRef will be used many times at
> various points, so a
> simplified example is...

Okay.  I'll take you at your word that this is necessary.  You should
consider the possibility that the overall design could be improved. 
But, assuming you really need to write the code that way, one possible
alternative would be to use an anonymous method:

    delegate type declared somewhere:

    delegate void SetField(int valueNew);


    then in a method somewhere:

    Settings set = new Settings();
    SetField setter;

    if (???)
        setter = delegate(int valueNew) { set.left = valueNew; };
    else if (???)
        setter = delegate(int valueNew) { set.right = valueNew; };
    else
        setter = delegate(int valueNew) { set.centre = valueNew; };

    setter(...);

    Some general code

    setter(...);

    Some general code

    setter(...);

    etc...

Actually, I should learn more about lamba expressions.  I suspect that
the syntax would be nicer with one.  I wonder if you could even get
away without having to declare the delegate type using a lamba
expression.  Maybe someone more knowledgeable will comment.  In the
meantime, the above should work.

Pete
Author
29 Nov 2007 7:17 PM
Marc Gravell
> lamba expressions.  I suspect that
> the syntax would be nicer with one.
I'll comment on the lambda syntax, but I'm undecided whether this is a
good use case:

Action<int> setter;
....
setter = newValue => set.left = newValue;

However - perhaps the bigger concern here is the impact of "captured
variables"; you might have to be very careful; not enough info to
assess if this is a problem.

> I wonder if you could even get away without having to declare the delegate type
> using a lamba expression.
Not really (unless it is obvious and "var"), but it would be "in
vogue" to use Action<int> here.

Marc
Author
28 Nov 2007 2:53 AM
Peter Webb
"Marc Gravell" <marc.grav***@gmail.com> wrote in message
news:a83597b1-517a-48ed-8659-aedeb7bb7b3d@f3g2000hsg.googlegroups.com...
>> "If you want a type to behave like a reference type, you should make it a
>> reference type to start
>> with." How do I make an integer a reference type?
>
> You don't; you make Settings a reference type by changing "struct" to
> "class". It is normally *very* rare to write a "struct" in .net, and
> usually relates to discreet (but possibly compound) "values" - such as
> a CompexInt32 or TimeRange.
>

That's interesting. As a beginner, I haven't really used structs much at
all - just a couple for the purposes of seeing what they do. I haven't used
them more, because I couldn't actually see any benefit of structs over
classes (except possibly a microscopic performance gain). I have felt guilty
about this, as I am not using what appeared to be a major part of the
language.

Are you now telling me that I needn't feel guilty about pretty much ignoring
struct types?
Author
28 Nov 2007 3:02 AM
Peter Duniho
On 2007-11-27 18:53:25 -0800, "Peter Webb"
<webbfamily@DIESPAMDIEoptusnet.com.au> said:

> That's interesting. As a beginner, I haven't really used structs much
> at all - just a couple for the purposes of seeing what they do. I
> haven't used them more, because I couldn't actually see any benefit of
> structs over classes (except possibly a microscopic performance gain).
> I have felt guilty about this, as I am not using what appeared to be a
> major part of the language.
>
> Are you now telling me that I needn't feel guilty about pretty much
> ignoring struct types?

That's right.  :)

Actually, there are real benefits to using a struct in certain
situations.  They can perform better in some cases.  For example, when
you have a lot of them and can allocate an array to contain the
collection (e.g. an actual Array, or some generic collection that uses
an array to store the values).

Of course, being a value type, they can also reduce performance if used
inappropriately.  And they have subtly different semantics than
reference types, which can result in hard-to-identify bugs (especially
if the structs are mutable).

I would say that in the long run, you'll probably want to at least
spend some time learning about structs, how they are different from
classes, and why you might use them.  Even if you never use a struct,
you'll at least understand better why you're not using them.  Also,
since a lot of what makes a struct different from a class is the same
as what makes any value type different from a class, understanding
structs will help you understand the other value types as well.

Pete
Author
28 Nov 2007 11:13 AM
Jon Skeet [C# MVP]
On Nov 28, 2:53 am, "Peter Webb"
<webbfam...@DIESPAMDIEoptusnet.com.au> wrote:
> That's interesting. As a beginner, I haven't really used structs much at
> all - just a couple for the purposes of seeing what they do. I haven't used
> them more, because I couldn't actually see any benefit of structs over
> classes (except possibly a microscopic performance gain).

It's not really about performance gain, usually - it's about reference
type semantics vs value type semantics.

> I have felt guilty
> about this, as I am not using what appeared to be a major part of the
> language.
>
> Are you now telling me that I needn't feel guilty about pretty much ignoring
> struct types?

Well, you're not *really* ignoring structs - you're just not creating
your *own* struct types.
Whenever you use int, Guid, long, float, byte etc you're using
structs.

It's a bit like generics - many people will never need to write their
own generic type or generic method (although I'd argue there's often a
lot of benefit for doing so) - but they may well *use* the existing
generic collections.

Jon

AddThis Social Bookmark Button