Creating a reference to a value type

I need to create a variable that holds a reference to a value type so that something like the following will work:



int i = 0;
int x = i;
i = 2;  // i need: i == 2 AND x == 2

 


This obviously works with reference types:



DataSet ds = new DataSet();
DataSet ds2 = ds;
ds.Tables.Add("Table1");  // now ds AND ds2 have 1 table (they reference the same object).

 


I thought that boxing a value type would create a reference, but it doesn't:



int i = 0;
object o = i;
o = 4; // But: i != 4
i = 8; // But: o != 8

 


So, how can I create a reference (NOT a pointer) to a value type

EDIT: I'm not sure it matters, but I'm using .NET 2.0.



Answer this question

Creating a reference to a value type

  • Justdeserves

    That's a good suggestion, however, because of my attempt to simplify the dillema, I've also neglected to mention the issue is a little bigger than this.  First of all, there will likely be no particular pattern relating one stored procedure to another and the references between output and input parameters between them will be haphazard, at best; so, I still would need a way to flexibly assign references.  Secondly, not only might I need to make references to output parameters from input parameters, but I might also need to reference other arbitrary value types; for instance, I need to allow the user to create an input parameter that references the selected value of a listbox or a dropdownlist or a textbox (among other controls).  I also need to allow the user to create references to values in some arbitrary dictionary (key/value paired) collection.

    Anyway, I think I came up with a solution for it.  I used Hath's suggestion and created a sort of wrapper for the value type and created a collection of these wrappers.  Then I created classes that represent sql parameters and made references to these objects from the parameter's Value property.  So now when one output procedure is executed and its Value property is set by Sql Server what really happens is the value of the wrapper class (in the collection) is set because of the reference.  Now, another stored procedure's input parameter can reference the same object and when executed can pull out the correct value.  It's kind of messy, but its the only way I can come up with.

    Like I said, the issue is really a lot larger than I've described, but I've done my best to avoid confusion (plus I'm way too lazy to actually sit here and explain the entire problem in full detail.)  =)

    Thanks for everyone's help.  If anyone ever comes up with a more elegant solution, please feel free to post it here.

  • juliam

    It's a good idea, Hath, but I'm not sure it will work for this situation.  Although the code you posted is true, I still can't use it to reference an already existing value type:



    int z = 3;
    ValueType i = new ValueType(z);
    z = 7;  // But: i.Value == 3

     


    Unfortunately, I think something like your solution may be my only option... I'm just not quite sure how to implement it yet.

    Is this an uncommon problem   I can't imagine no one has ever needed to reference a value type before...

  • dharmendra singh

    Hi,

    No workaround on that. You need to use a pointer. You could declare pointers in C# only on unsafe codes...

    If my memory serves me right there's a reference operator in C++/CLI. Its for managed value classes. The operator is '%'. That is being used instead of a pointer...

     

     

    cheers,

    Paul June A. Domag



  • Vijey Ashok

    Haha, I'll try to explain, but it's a very complex project.  I'll try to simplify it the best I can to make the problem more obvious:

    A client I've recently taken on requires an application to be built that allows an end user to create a project that contains a list of stored procedures that need to be executed in a particular order (there's much more to it than this, but this is the problematic piece).  Each stored procedure may have any number of input/output parameters.  Essentially, this is what happens at this stage:



    // user does some action that creates a new project (e.g. File > New)
    MyProject project = new MyProject();

    // user does some action that adds a new stored procedure to the list
    SqlCommand cmd = new SqlCommand(new SqlConnection(someConnectionString));
    cmd.CommandText = "spSomeProcedure";
    cmd.Parameters.Add(new SqlParameter("@SomeParam", someValue));
    project.StoredProcedures.Add(cmd);

    // user saves (serializes) the project graph
    BinaryFormatter.Serialize(project, somePath);

     


    This is simple enough when the values of these parameters remain static.  However, problems arise when the parameter values become dynamic.  Lets say the user adds another stored procedure and that stored procedure #2 has an input parameter that should be a reference to an output parameter of stored procedure #1:



    // user does some action that creates a new project (e.g. File > New)
    MyProject project = new MyProject();

    // user does some action that adds a new stored procedure to the list
    SqlCommand cmd = new SqlCommand(new SqlConnection(someConnectionString));
    cmd.CommandText = "spSomeProcedure";
    cmd.Parameters.Add(new SqlParameter("@SomeParam", someValue));
    cmd.Parameters.Add(new SqlParameter("@SomeOutputParam", null));
    project.StoredProcedures.Add(cmd);

    // user does some action that adds a new stored procedure to the list
    SqlCommand cmd = new SqlCommand(new SqlConnection(someConnectionString));
    cmd.CommandText = "spSomeOtherProcedure";
    cmd.Parameters.Add(new SqlParameter("@DependentParam", project.StoredProcedures[0].Parameters[0].Value));  // here's the problem
    project.StoredProcedures.Add(cmd);

    // user saves (serializes) the project graph
    BinaryFormatter.Serialize(project, somePath);

     


    So, what happens is that instead of assigning the reference to the value of the parameter in the first stored procedure, it assigns the value at that particular moment (null).

    Later on, the user deploys this project to a web application that deserializes the project and fires off the specified stored procedures:



    // in web application
    MyProject project = BinaryFormatter.Deserialize(somePath) as MyProject;

    foreach(SqlCommand cmd in project.StoredProcedures)
       cmd.ExecuteNonQuery();


     


    (I should mention that I've created wrapper classes for SqlCommands that allow them to be serialized and deserialized.)

    So, now, the stored procedures are fired off.  When the first one executes, the output parameter is populated with some value.  However, when the second one is fired off the value of its parameter is never updated (because it's not a reference, its a value).

    I hope that's clear enough.  Let me know if I'm ambiguous about anything important.

    Thanks for your (and anyone else's) help!

    EDIT: I guess the code samples dont handle comments very well :-\

  • Sandeep Arora

    Why are you trying to do this   It'll help to understand the scenario to give a solution.


  • Nile

    Not what I wanted to hear.  :(  Unfortunately, I can't user a pointer because the class that requires this functionality is serialized and deserialized.  So, although before deserialization the pointer would correctly refer to the value, after deserialization I would imagine the pointer is no longer correct (I haven't tried it, but I'm almost certain).

    Any suggestions as to how I could create some sort of wrapper class to solve this issue

  • Desoohn

     rgerbig wrote:
    Hi,

    if you want to copy a reference of a parameter to a method youcan use this:

    http://msdn.microsoft.com/library/default.asp url=/library/en-us/csref/html/vclrfRef.asp


    Did you not read my post at all   You must not have because 1.) I never once mentioned needing to pass a parameter by reference and 2.) you probably would have realized I'm a far more advanced programmer than anyone that would ever need to refer to a document that covers such a ridiculously simple topic.

    While I appreciate any help I can get on the solution to my problem, I do request that anyone offering help read and understand the previous posts before giving any sort of advice or suggestions.

  • SoccerSarah

    could you not create a wraper class for your value type

    ps not an expert.. so don't flame me.




    public class ValueType

    {

    private object _value;

    public object Value

    {

    get { return this._value; }

    set { this._value = value; }

    }

    public ValueType(object value)

    {

    this._value = value;

    }

    }


     





    ValueType i = new ValueType(0);

    ValueType x = i;

    x = i;

    i.Value = 2;

    if (x == i)

    {

    MessageBox.Show("x == i");

    }


     




  • Mahmood Salamah

    From your sample code (thanks for that sample code - that was very useful), I'd suggest you create a wrapper for StoredProcedures (which I think is a collection of SqlCommands) and have a method on it, say ExecuteNonQueries, which runs all the Sql commands one by one.

    Then you can come up with some kind of notation that you can use to pass the output of previous queries to the current query. 

    Before the "ExecuteNonQueries" method calls the "ExecuteNonQuery" on the current SqlCommand, it will go thru all the query params and make sure they're filled in, from the previous results.

    This is one way to work around this problem. 

    HTH


  • ananda vardhana

    Hi,

    if you want to copy a reference of a parameter to a method youcan use this:

    http://msdn.microsoft.com/library/default.asp url=/library/en-us/csref/html/vclrfRef.asp

  • Creating a reference to a value type