Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / February 2008

Tip: Looking for answers? Try searching our database.

By Ref but inside a method.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Rene - 26 Feb 2008 23:01 GMT
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!
Peter Duniho - 26 Feb 2008 23:56 GMT
> So I am fooling around having some fun and I came up with the class  
> below:
[quoted text clipped - 18 lines]
> [...]
> 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 allow you  
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
Jon Skeet [C# MVP] - 27 Feb 2008 00:00 GMT
> So I am fooling around having some fun and I came up with the class below:
>
[quoted text clipped - 31 lines]
> 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);
   }
}

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Jesse McGrew - 27 Feb 2008 13:43 GMT
> So I am fooling around having some fun and I came up with the class below:
>
[quoted text clipped - 32 lines]
> 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
Rene - 27 Feb 2008 20:13 GMT
Thanks guys, this is really neat stuff.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.