C# marshal-by-reference
-
// In this example, frmEntry has a public decimal named amount.
frmEntry entry_form = new frmEntry();
if (entry_form.ShowDialog() == DialogResult.Yes)
{
// Actual intent. Causes CS0197.
lblValue.Text = discount_form.amount.ToString("f");// This works. decimal a = entry_form.amount; lblValue.Text = a.ToString("f"); // Microsoft's "fix" // See http://msdn.microsoft.com/library/en-us/cscomp/html/vcerrCompilerErrorCS0197.asp lblValue.Text = ((decimal)((object)(entry_form.amount))).ToString("f");
}
-
Sounds like that should be a property, not a member variable. If not, a method works but it will be dirty.
Looks like another case of a leaky abstraction. Marshal-by-reference...well I'm not familiar with COM enough to know what that means, unfortunately.
-
I have no idea. The problem seems to be the .ToString, because in the real code, there is also a public boolean that I can access just fine. (eg. if (entry_form.percent) lblValue.Text += "%";)
-
Makes sense to me. If frmEntry inherits from MarshalByRefObject then .NET considers it to be capable of being a proxy. Therefore, you can't pass a field of it because you might be crossing process boundaries (which would break things). So you have to extract the value from its object. Assigning the value to a local variable makes a copy on the stack that you can use. Casting the decimal to a double would create a copy on the stack and then you can use that copy.
For C++ people: Think about passing a pointer to a variable to another machine or another process on the same machine. The pointer would mean nothing. C# recognizes that you might be doing that and tells you no. So you have to pass by value, not by reference. It's just a rare side effect of trying to hide pointers from you.
-
@danguy said:
// In this example, frmEntry has a public decimal named amount.
frmEntry entry_form = new frmEntry();
if (entry_form.ShowDialog() == DialogResult.Yes)
{
// Actual intent. Causes CS0197.
lblValue.Text = discount_form.amount.ToString("f");// This works. decimal a = entry_form.amount; lblValue.Text = a.ToString("f"); // Microsoft's "fix" // See http://msdn.microsoft.com/library/en-us/cscomp/html/vcerrCompilerErrorCS0197.asp lblValue.Text = ((decimal)((object)(entry_form.amount))).ToString("f");
}
Don't know much about C#, but in your failing code you're referencing "discount_form", but in both the workaround and MS's "fix" you're referencing "entry_form" ...
-
Well, I guess that is what happens when you are not careful enough when anonymizing code. Thay are all the same form, and it is just a regular WinForm.
-
@danguy said:
// In this example, frmEntry has a public decimal named amount.
frmEntry entry_form = new frmEntry();
if (entry_form.ShowDialog() == DialogResult.Yes)
{
// Actual intent. Causes CS0197.
lblValue.Text = discount_form.amount.ToString("f");// This works. decimal a = entry_form.amount; lblValue.Text = a.ToString("f"); // Microsoft's "fix" // See http://msdn.microsoft.com/library/en-us/cscomp/html/vcerrCompilerErrorCS0197.asp lblValue.Text = ((decimal)((object)(entry_form.amount))).ToString("f");
}
<FONT color=#ffffff><troll></FONT>The real WTF is C#<FONT color=#ffffff></troll></FONT>
-
@Some Idiot said:
<font color="#ffffff"><troll></font>The real WTF is C#<font color="#ffffff"></troll></font>
Nice tags. :-P