I have the following code
char ptr=new char();
int counter = 1;
string s = new System.String(ptr, counter);
// does not show something
MessageBox.Show(s+"Something");
//shows something
MessageBox.Show("Something" + s);
The first Messagebox shows nothing
The Second Messagebox shows something
If the counter value is 0 then both messagebox shows same result but if counter is greater than 0 then the problem occurs.
I think the problem is with new string(ptr, counter)
initilization
. But I want to know the internal mechnism why this is occured.
String is immutable. That is, its content cannot be modified once it is created. For example, the method toUpperCase() constructs and returns a new String instead of modifying the existing content.
The Java String is immutable which means it cannot be changed. Whenever we change any string, a new instance is created. For mutable strings, you can use StringBuffer and StringBuilder classes. We will discuss immutable string later. Let's first understand what String in Java is and how to create the String object.
ptr
is a null character ('\0'
) and s
is a string
with one copy of that character (i.e. "\0"
). So, at runtime, your first call's parameter evaluates to "\0Something"
whereas your other one evaluates to "Something\0"
.
In C#, string
s are allowed to have null characters; you can conceptualize them as just a char[]
array (which has a known length); So null characters are OK. The issue comes about when you pass to a C API. C doesn't have strings, so they're immitated using null-terminated strings. As far as any C API is concerned, "\0Something"
is an empty string (strlen
would return 0). So, when you use MessageBox.Show
, your string is passed on down to the Win32 API function, MessageBoxW
which only understands null-terminated strings.
From the .NET source code for MessageBox.Show(string)
public static DialogResult Show(string text)
{
return ShowCore(null, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, 0, false);
}
Towards the end of ShowCore
, we see this line:
return (DialogResult)MessageBoxW(handle, text, caption, style);
And that MessageBoxW
call is that Win32 API function in user32.dll
.
new char()
returns an empty character (contains two zero bytes), so ptr
is '\0'
.
When you use s = new System.String(ptr, 0);
, the constructor concatenates the '\0'
character zero times, resulting in an empty string (""
). Adding the empty string to another string has no effect, so s+"Something"
is equal to "Something"+s
which is "Something"
.
In another way, using s = new System.String(ptr, 1);
creates a string containing a single '\0'
character. Then adding this string before "Something"
results in "\0Something"
where adding after it results in "Something\0"
.
In C# strings are not manipulated as NULL-Terminated Strings, so when you create "\0Something"
, you really have it (you can make sure by taking the Length
of the string which is 10), however MessageBox.Show
is converted to Win32 MessageBox
function of the windows user32 library. And that function requires a null-terminated string (it stops when encounters a zero byte or two zero bytes for unicode strings).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With