Assigning a reference to a variable

  • Thread starter Thread starter Jon
  • Start date Start date
J

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?
 
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
 
Jon said:
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());
 
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 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?
 
"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
 
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 said:
"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
 
[...]
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
 
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.
 
Marc Gravell said:
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?
 
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
 
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


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


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


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
 
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
 
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
 
Hi Jon,

Thanks for your feedback.

I think Peter has provided very good discussion and suggestion to you.
Below is some other comment:

From another perspective, I do not think using a general intRef
pointer/reference for different purpose and different places is a best
practise. It would make the code review and Refactor a bit harder. For
example, it is hard for the reviewer to understand the logic meaning of
intRef variable in a big function. So it may be good to assgin these int
variables directly without using a intRef variable as indirection. However,
I agree that this may not be a big problem. Just a thought for
consideration. 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.
 
Jon.. In C++ if *p is a very large object then passing p may avoid a
call to the copy constructor. In C++ classes use value semantics by
default, but in C# classes use reference semantics. So in C# you can
simply return a reference to an object and not worry about a call to the
copy constructor.

We can demonstrate this difference in C++/CLI since C++/CLI supports
both value semantics and reference semantics, unlike C#. So in C++/CLI
if you have ref class SomeClass you can create an object using reference
semantics as in:

SomeClass^ someClass= gcnew SomeClass(); or you can use value semantics
as in:

SomeClass someClass();

SomeClass^ someClass1= someClass does not call the copy constructor.

SomeClass someClass2= someClass does call the copy constructor, but only
in C++/CLI. I don't know of any equivalent in C#.

Another reason to use indirection is to provide read only access to a
variable. This is possible in C++ using the const key word, but const is
not supported in C#. To proved read only access to a read/write
variable, in C# you can wrap a reference to the read/write class in a
wrapper class that simply provides pass through get only access to the
variable using delegation.

Regards,
Jeff
 

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

Back
Top