Pointer to string in C#

  • Thread starter Thread starter Mike
  • Start date Start date
M

Mike

WARNING: newbie to C#

Is there a way to do this:

WCHAR szString[] = L"This is your girlfriends string";
LPWSTR pszString = szString; // This is a pointer to her string
wcscpy(pszString, L"And now I touch it!");

in C#?

Something like this:

string strText = "This is C# string";
object objText = strText; // I want this to be a pointer to that string
objText = "But this doesn't change strText";

but then working please! ;o)

From the description in MSDN strText.Clone() looked promising, but no...

Reason I want to do this is prevent having to duplicate "Leave"
eventcode for every textbox on my form:

this.txtCompany.Text = customerClass.Company.Name;
this.txtCompany.Tag = customerClass.Company.Name;
this.txtCompany.Leave += new EventHandler(txtOnLostFocus);

this.txtCompanyAddress.Text = customerClass.Company.Address;
this.txtCompanyAddress.Tag = customerClass.Company.Address;
this.txtCompanyAddress.Leave += new EventHandler(txtOnLostFocus);

private void txtOnLostFocus(object sender, EventArgs e)
{
TextBox txt = (TextBox)sender;
if (txt.Tag.ToString() != txt.Text)
txt.Tag = txt.Text;
// In the case of a Leave event on txtCompany,
// customerClass.Company.Name should change
// In the case of a Leave event on txtCompanyAddress,
// customerClass.Company.Address should change
}


I understand there is probably a better way to achieve what I want but
I'm too new to C# to think of it...

Thanks guys/girls!
 
string strText = "This is C# string";
object objText = strText; // I want this to be a pointer to that string

Yes, at this point you have two variables referring to the same
string.

objText = "But this doesn't change strText";

The difference in C# is that you can't change a string (like you did
with wcscpy). .NET strings are immutable.

TextBox txt = (TextBox)sender;
if (txt.Tag.ToString() != txt.Text)
txt.Tag = txt.Text;
// In the case of a Leave event on txtCompany,
// customerClass.Company.Name should change
// In the case of a Leave event on txtCompanyAddress,
// customerClass.Company.Address should change

Well the eaasy solution would be to write

if (sender == txtCompany)
customerClass.Company.Name = txt.Text;
else if (sender == txtCompanyAddress)
customerClass.Company.Address = txt.Text;

But you may also want to look at data binding.


Mattias
 
[...]
string strText = "This is C# string";
object objText = strText; // I want this to be a pointer to that string
objText = "But this doesn't change strText";

but then working please! ;o)

Let's get the whole "pointer to string" thing out of the way. There's not
really any way to do that in C#, except possibly with "unsafe" code. But
given your description so far, I doubt you really want a pointer to a
string. Surely we can come up with some way to do what you want without
actually needing a reference to a string reference.

So, let's look at your code:
From the description in MSDN strText.Clone() looked promising, but no....

Reason I want to do this is prevent having to duplicate "Leave"
eventcode for every textbox on my form:

this.txtCompany.Text = customerClass.Company.Name;
this.txtCompany.Tag = customerClass.Company.Name;
this.txtCompany.Leave += new EventHandler(txtOnLostFocus);

this.txtCompanyAddress.Text = customerClass.Company.Address;
this.txtCompanyAddress.Tag = customerClass.Company.Address;
this.txtCompanyAddress.Leave += new EventHandler(txtOnLostFocus);

private void txtOnLostFocus(object sender, EventArgs e)
{
TextBox txt = (TextBox)sender;
if (txt.Tag.ToString() != txt.Text)
txt.Tag = txt.Text;
// In the case of a Leave event on txtCompany,
// customerClass.Company.Name should change
// In the case of a Leave event on txtCompanyAddress,
// customerClass.Company.Address should change
}

So, I have the impression you want changes in the Text property to be
reflected in the associated property in a given class instance.

I can think of at least three different ways to do that. One involves
reflection, which I try to stay away from so I'm going to ignore that.
:) The second involves data binding. I'm no expert, so there might be a
better way to implement data binding than how I show it here. But you can
do something like this:

this.txtCompany.DataBindings.Add("Text", customerClass.Company,
"Name");
this.txtCompanyAddress.DataBindings.Add("Text", customerClass.Company,
"Address");

By default, the property should be updated on validation, so as long as
the control is validating (which it would be by default) the property will
get set properly (validation usually happens when focus leaves the
control). Using this method, you don't even need to initialize the
control, nor provide an event handler for the Leave event.

The third way uses an anonymous method. In this particular scenario, I
think it's the clumsy way to do it. But seeing the technique you may find
it useful for other things in the future (just keep in mind that as was
the case here, there might be an easier way :) ):

// This creates an anonymous method that will copy the control's Text
property to
// class's corresponding property.
this.txtCompany.Tag = delegate() { customerClass.Company.Name =
this.txtCompany.Text; }

// Alternatively, if you really want to check the previous value first:
this.txtCompany.Tag = delegate() { if (customerClass.Company.Name!=
this.txtCompany.Text) customerClass.Company.Name = this.txtCompany.Text; }

then in the Leave handler:

private void txtOnLostFocus(object sender, EventArgs e)
{
TextBox txt = (TextBox)sender;
MethodInvoker setter = (MethodInvoker)txt.Tag;

// This line of code executes the anonymous method you created
before. Since each
// control would have a different anonymous method, assigning the
control's Text
// property to the appropriate data property, executing it here
accomplishes what
// you want.
setter();
}

This sort of thing can work pretty much anywhere there's some specific
code you want to execute every time for a specific situation, but you
don't want to have to create a whole new named method each time. It's
especially common when using Control.Invoke() or predicates for the
various generic collection search, sorting, etc. methods. Using it here
is kind of contrived. :)

Pete
 
Very cool! Didn't know about databindings, thanks for the excellent
explanation, got it working perfectly with databindings now.

Mike.



Peter said:
[...]
string strText = "This is C# string";
object objText = strText; // I want this to be a pointer to that string
objText = "But this doesn't change strText";

but then working please! ;o)

Let's get the whole "pointer to string" thing out of the way. There's
not really any way to do that in C#, except possibly with "unsafe"
code. But given your description so far, I doubt you really want a
pointer to a string. Surely we can come up with some way to do what you
want without actually needing a reference to a string reference.

So, let's look at your code:
From the description in MSDN strText.Clone() looked promising, but no...

Reason I want to do this is prevent having to duplicate "Leave"
eventcode for every textbox on my form:

this.txtCompany.Text = customerClass.Company.Name;
this.txtCompany.Tag = customerClass.Company.Name;
this.txtCompany.Leave += new EventHandler(txtOnLostFocus);

this.txtCompanyAddress.Text = customerClass.Company.Address;
this.txtCompanyAddress.Tag = customerClass.Company.Address;
this.txtCompanyAddress.Leave += new EventHandler(txtOnLostFocus);

private void txtOnLostFocus(object sender, EventArgs e)
{
TextBox txt = (TextBox)sender;
if (txt.Tag.ToString() != txt.Text)
txt.Tag = txt.Text;
// In the case of a Leave event on txtCompany,
// customerClass.Company.Name should change
// In the case of a Leave event on txtCompanyAddress,
// customerClass.Company.Address should change
}

So, I have the impression you want changes in the Text property to be
reflected in the associated property in a given class instance.

I can think of at least three different ways to do that. One involves
reflection, which I try to stay away from so I'm going to ignore that.
:) The second involves data binding. I'm no expert, so there might be
a better way to implement data binding than how I show it here. But you
can do something like this:

this.txtCompany.DataBindings.Add("Text", customerClass.Company,
"Name");
this.txtCompanyAddress.DataBindings.Add("Text",
customerClass.Company, "Address");

By default, the property should be updated on validation, so as long as
the control is validating (which it would be by default) the property
will get set properly (validation usually happens when focus leaves the
control). Using this method, you don't even need to initialize the
control, nor provide an event handler for the Leave event.

The third way uses an anonymous method. In this particular scenario, I
think it's the clumsy way to do it. But seeing the technique you may
find it useful for other things in the future (just keep in mind that as
was the case here, there might be an easier way :) ):

// This creates an anonymous method that will copy the control's
Text property to
// class's corresponding property.
this.txtCompany.Tag = delegate() { customerClass.Company.Name =
this.txtCompany.Text; }

// Alternatively, if you really want to check the previous value first:
this.txtCompany.Tag = delegate() { if (customerClass.Company.Name !=
this.txtCompany.Text) customerClass.Company.Name = this.txtCompany.Text; }

then in the Leave handler:

private void txtOnLostFocus(object sender, EventArgs e)
{
TextBox txt = (TextBox)sender;
MethodInvoker setter = (MethodInvoker)txt.Tag;

// This line of code executes the anonymous method you created
before. Since each
// control would have a different anonymous method, assigning the
control's Text
// property to the appropriate data property, executing it here
accomplishes what
// you want.
setter();
}

This sort of thing can work pretty much anywhere there's some specific
code you want to execute every time for a specific situation, but you
don't want to have to create a whole new named method each time. It's
especially common when using Control.Invoke() or predicates for the
various generic collection search, sorting, etc. methods. Using it here
is kind of contrived. :)

Pete
 
Back
Top