-1

I would like to pass the reference of a variable into a class, use it and then get it out later.

Something like this:

// Create the comment Screen
string newCommentText = "";
commentsScreen = new CommentEntry(this, ref newCommentText);

commentScreen.ShowDialog();

...

_dataLayer.SaveOffComment(newCommentText);

And then in the comment class:

public partial class CommentEntry : Form
{
    public CommentEntry(Control pControl, ref string commentResult)
    {
        InitializeComponent();
        control = pControl;

        // ***** Need a way for this to store the reference not the value. *****
        _commentResult = commentResult;  
    }


    private string _commentResult;

    private void CommentEntry_Closing(object sender, CancelEventArgs e)
    {
        _commentResult = tbCommentText.Text.Trim();
    }
}

Is there someway that newCommentText can have the value set in _commentResult in the closing method?

NOTE: Clearly it would be easy to just set a variable in my class and access it after the ShowDialog. This example is only a an approximation of my real issue and accessing any variables in the class after ShowDialog is done is not possible.

Vaccano
  • 78,325
  • 149
  • 468
  • 850
  • 2
    You could always wrap the value in a class. – Nick Larsen Jul 06 '10 at 20:33
  • 1
    It sounds like you want a pointer, not a reference. – Biff MaGriff Jul 06 '10 at 20:34
  • Why can't you access any properties in the class after `ShowDialog` has returned? – ChrisF Jul 06 '10 at 20:38
  • @Andy, I am having to "Roll my own" `ShowDialog` method. It is really a call to `Show` that waits until the window closes. This causes all variables in the dialog to be lost after it closes. See this question for more info as to why I had to roll my own: http://stackoverflow.com/questions/3105438/how-to-attach-messages-from-a-form-shown-with-showdialog-to-application2 – Vaccano Jul 06 '10 at 20:38

5 Answers5

3

This will never work with a String as they are immutable and the variable will change to point to a new instance.

You have two basic options. The first is to simply have a getter for the result so it can be accessed when it is needed later. The other option is to have the owner pass in a delegate method that can be called passing in the resulting value. The owner would then receive the value when the CommentEntry is closing.

unholysampler
  • 17,141
  • 7
  • 47
  • 64
2

You generally can't directly store a 'reference to a reference' in C#, but you could do something like this:

public interface ICommented
{
    string Comment { get; set; }
}

public class MyClass : ICommented
{
    public string Comment { get; set; }
}

public partial class CommentEntry : Form
{
    public CommentEntry(Control pControl, ICommented commented)
    {
        InitializeComponent();
        control = pControl;

        // ***** Need a way for this to store the reference not the value. *****
        _commented = commented;
    }


    private ICommented _commented;

    private void CommentEntry_Closing(object sender, CancelEventArgs e)
    {
        _commented.Comment = tbCommentText.Text.Trim();
    }
}

So now your form can edit the comment of any class that has said it knows how to be commented upon.

Dan Bryant
  • 27,329
  • 4
  • 56
  • 102
2

As Dan Bryant pointed out, you cannot do that directly. One option is to wrap the reference into a class, but that requires writing a lot of boilerplate code. A simpler option is to use delegate and lambda functions (in C# 3.0) or anonymous delegates (C# 2.0):

string newCommentText = ""; 
// Using lambda that sets the value of (captured) variable
commentsScreen = new CommentEntry(this, newValue => {
  newCommentText = newValue });  
commentScreen.ShowDialog(); 
_dataLayer.SaveOffComment(newCommentText); 

A modified version of the CommentEntry form would look like this:

public partial class CommentEntry : Form { 
  public CommentEntry(Control pControl, Action<string> reportResult) { 
    InitializeComponent(); 
    control = pControl; 
    // Store the delegate in a local field (no problem here)
    _reportResult = reportResult;    
  } 

  private Action<string> _reportResult; 

  private void CommentEntry_Closing(object sender, CancelEventArgs e) { 
    // Invoke the delegate to notify the caller about the value
    _reportResult(tbCommentText.Text.Trim()); 
  } 
} 
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
0

Make newComment property of CommentEntry class.

STO
  • 10,390
  • 8
  • 32
  • 32
  • As I said in the note at the end of my question, I cannot acces any variables of the class after ShowDialog – Vaccano Jul 06 '10 at 20:36
0

Here, try out what this guy is doing. http://www.c-sharpcorner.com/UploadFile/gregory_popek/WritingUnsafeCode11102005040251AM/WritingUnsafeCode.aspx

Biff MaGriff
  • 8,102
  • 9
  • 61
  • 98