Empty string

  • Thread starter Thread starter M D
  • Start date Start date
M

M D

You know how you assume you know until you find out you don't know.

Well, I typed into a function definition "..., new String("")).

I know what I want. Everyone reading this knows what I want. However,
the 1.0 compiler has no idea what I want.

Can anyone share with me the syntax that will actually communicate the
concept to the compiler, please?

thx
md
 
Actually I'm not sure what you want to accomplish. Creating a new
string with "new String()" automatically creates a zero length string.
So why use quotation marks?

Best Regards
Johann Blake
 
M said:
You know how you assume you know until you find out you don't know.

Well, I typed into a function definition "..., new String("")).

I know what I want. Everyone reading this knows what I want.
However, the 1.0 compiler has no idea what I want.

Can anyone share with me the syntax that will actually communicate the
concept to the compiler, please?

thx
md

Why not use just "" ?
It's a bit of overkill to create a new string-object that you supply with
a string-literal (which is also a string-object) that has exactly the same
value as you want to end up with...

You could also use the predefined constant String.Empty.

By the way, 1.1 has been out for quite some time ...

Hans Kesting
 
I second this, use the constant String.Empty, instead of using a magic
value. It's just better practice.
 
new String(): "No overload for method 'String' takes '0' arguments"

I need to create a new string on the heap for the top of a recursive
method. Wouldn't just foo(..., "") reference a constant on the string
table, ie an immutable object?

I haven't been given the VS.net version beyond the first, hence 1.0.

thx
md
 
Hi M.D

if you really have to use a new instance of string, use:
string.Copy("")

but there really is no use of that other, than demonstrating the difference
of value and reference comparison.

Christof
 
Nicholas Paldino said:
I second this, use the constant String.Empty, instead of using a magic
value. It's just better practice.

In what way is it better practice than ""? They're both effectively
magic values in a way - it's not like using "foo" in two different
places, where you could accidentally change "foo" in one place but not
in another, but change the value in one place if you had it defined as
a constant. In this case, you'll never be able to change the value of
String.Empty anyway...

I've heard several people say that it *is* better to use String.Empty,
but never any believable reasons why. Personally I find "" more
readable.
 
Jon,

It really lends itself to maintaining discipline more than anything
else. In this case, I would say that there is a good arguement for "".
However, it is because of special conditions such as this that other
deviations from the practice become accepted. If there was actually a value
there, I am sure you would argue that a named constant should be used, for a
number of reasons. If the OP's value was subject to change, I would
actually recommend him using a named constant of his own (and not
String.Empty) and use that instead.

The interesting part about this is that I would not use a constant for
something such as 0 (when starting a loop) or 1 (for incrementing something
by one). Everyone has different tolerances, the empty string falls outside
of mine in this case.

For me, I just find it easier to adhere to an absolute rule instead of
having special cases (and admittedly, this is one of those cases where the
value isn't readily apparent). The more special cases you have, the more
you have to remember what they are, and the more subject your code is to
bugs.
 
Nicholas Paldino said:
It really lends itself to maintaining discipline more than anything
else. In this case, I would say that there is a good arguement for "".
However, it is because of special conditions such as this that other
deviations from the practice become accepted. If there was actually a value
there, I am sure you would argue that a named constant should be used, for a
number of reasons. If the OP's value was subject to change, I would
actually recommend him using a named constant of his own (and not
String.Empty) and use that instead.
Absolutely.

The interesting part about this is that I would not use a constant for
something such as 0 (when starting a loop) or 1 (for incrementing something
by one). Everyone has different tolerances, the empty string falls outside
of mine in this case.

That's fine - but I think it's then a matter of personal preference
rather than best practice.
For me, I just find it easier to adhere to an absolute rule instead of
having special cases (and admittedly, this is one of those cases where the
value isn't readily apparent). The more special cases you have, the more
you have to remember what they are, and the more subject your code is to
bugs.

I think it depends on the readability for me - "" is more readable than
String.Empty, and it's an easy enough single value to remember as an
exception to the rule.
 
James Curran said:
Well, it's a monir point, but "String.Empty" is easier to search for, if
you needed to find everyplace it's used (searching for "" would trip you up
with false positives on strings like : @"Who said ""Which way did he
go?""?";

How many of those do you regularly have? ;)

(Personally I rarely use verbatim string literals just for the sake of
quotes, preferring \" to "".)

I suspect the number of minutes wasted on false positives when looking
for "" and finding other examples is vanishingly small. I'll take
readability over ease of searching any time.

(I know that some find String.Empty more readable, at which point it
certainly makes sense for them to use that instead. I just find the
idea that String.Empty is absolutely *better* than "" to be dodgy.)
 
I think you guys have missed the point.

What I had to do was create a string field at object level and
initialize it at the begining of each call to the recursion because ""
cannot be passed by ref as it is not an lvalue (as I suggested, it is on
the stack not the heap.) This is what I was trying to avoid as it is
poor form in object orientation where I should be able to create a new
String(), leave it nameless and under the perview of the garbage
collector once the recursion is complete.

I wouldn't have had this problem if I were creating, say, a new
StreamWriter. Or if there were a way to create a new empty string
object.

String.Copy("") is also not an lvalue.

thx
md
 
M D,
| Or if there were a way to create a new empty string
| object.
Have you tried:

String empty = new String('\0', 0)

Which creates a new empty string object.

Hope this helps
Jay


|I think you guys have missed the point.
|
| What I had to do was create a string field at object level and
| initialize it at the begining of each call to the recursion because ""
| cannot be passed by ref as it is not an lvalue (as I suggested, it is on
| the stack not the heap.) This is what I was trying to avoid as it is
| poor form in object orientation where I should be able to create a new
| String(), leave it nameless and under the perview of the garbage
| collector once the recursion is complete.
|
| I wouldn't have had this problem if I were creating, say, a new
| StreamWriter. Or if there were a way to create a new empty string
| object.
|
| String.Copy("") is also not an lvalue.
|
| thx
| md
|
|
 
Actually, I'm unclear what you what to do. The following works as you'd
expect:

public class MyClass
{
public static void Main()
{
MyClass m = new MyClass();
Console.WriteLine(m.Foo(10, ""));
}

public string Foo(int n, string str)
{
if (n == 0)
return str;
else
return String.Format("{0}-{1}", n, Foo(n-1, str));
}
}
==========================================
This also works as you'd expect:

public class MyClass
{
public static void Main()
{
MyClass m = new MyClass();
string str = "";
m.Foo2(10, ref str);
Console.WriteLine(str);
}

public void Foo2(int n, ref string str)
{
if (n == 0)
return ;
else
{
str += '-' + n.ToString();
Foo2(n-1, ref str);
return ;
}
}
}

================================================
This, on the other hand, seems to show the error you are getting:
public class MyClass
{
public static void Main()
{
MyClass m = new MyClass();
m.Foo2(10, ref "");
Console.WriteLine(str); /// what do you output here?
RL();
}


public void Foo2(int n, ref string str)
{
if (n == 0)
return ;
else
{
str += '-' + n.ToString();
Foo2(n-1, ref str);
return ;
}
}
}
========================================
That won't compile, but even if it did, it wouldn't work, because Foo2 is
generating output, but aren't saving it.

"ref" says "I'm giving you a place to put the answer", but you expressly
DON'T want to give it such a place. The problem isn't with the compile, but
with your code, which is not consistent with itself.
""
cannot be passed by ref as it is not an lvalue (as I suggested, it is on
the stack not the heap.)

No. "" is not an lvalue because it is NEITHER on the stack frame NOR on
the heap.

--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 
Jay B. Harlow said:
M D,
| Or if there were a way to create a new empty string
| object.
Have you tried:

String empty = new String('\0', 0)

Which creates a new empty string object.

Indeed it does - but I had to check. You see, the seemingly similar:

String empty = new String (new char[0]);

*doesn't* produce a new string on .NET 1.1. Instead, it returns the
same reference that "" or String.Empty do. This curiosity appears to
have been removed from .NET 2.0...
 
M D said:
I think you guys have missed the point.

That would be because you never actually spelled out the point -
nowhere in your previous posts did you mention that you wanted to pass
anything by reference.
What I had to do was create a string field at object level and
initialize it at the begining of each call to the recursion because ""
cannot be passed by ref as it is not an lvalue (as I suggested, it is on
the stack not the heap.)

The value of the local variable is on the stack, whatever the type is.
The string data itself is never on the stack.

See http://www.pobox.com/~skeet/csharp/memory.html
This is what I was trying to avoid as it is
poor form in object orientation where I should be able to create a new
String(), leave it nameless and under the perview of the garbage
collector once the recursion is complete.

I wouldn't have had this problem if I were creating, say, a new
StreamWriter.

Yes you would, if you'd wanted to use pass by reference. To pass
*anything* by reference, you have to have a variable, whether it's a
string or a StreamWriter.

It's possible that you're using pass-by-reference semantics
unnecessarily - see
http://www.pobox.com/~skeet/csharp/parameters.html

Also, building up a string should usually be done using a StringBuilder
rather than creating lots of temporary strings.
 
Jon,
I specifically checked 1.1 for new String('\0', 0), I didn't bother checking
new String (new char[0]), interesting it doesn't...

I had not tried 2.0 yet, as I've been busy with VSTO for Outlook on it.

Thanks for the additional info
Jay



| > M D,
| > | Or if there were a way to create a new empty string
| > | object.
| > Have you tried:
| >
| > String empty = new String('\0', 0)
| >
| > Which creates a new empty string object.
|
| Indeed it does - but I had to check. You see, the seemingly similar:
|
| String empty = new String (new char[0]);
|
| *doesn't* produce a new string on .NET 1.1. Instead, it returns the
| same reference that "" or String.Empty do. This curiosity appears to
| have been removed from .NET 2.0...
|
| --
| Jon Skeet - <[email protected]>
| http://www.pobox.com/~skeet
| If replying to the group, please do not mail me too
 
not just:

string mystring = "";
foo(ref mystring);

I wanted to call:

foo(ref new string('\0',0), 0); //such intuitive syntax
...
private foo(ref string scratch, int k) {
do some things;
foo(scratch, k+1)
do something with what was accumulated in scratch;
}

and NO

private string mystring = "";

Do they call that a anonomous object?

I've never used StringBuilder which is probably a better way except for
the month of study it would likely take to figure out MS wants it to be
used.

I thought my question was rather clear, "how do you make a new empty
string?" All the answers until someone (thank-you) came up with new
String('\0',0) insisted that "" was an object rather than some static
item on the string table!

I guess bad code is that which is not dedicated to a WinForm.

thx
md
 
M D said:
not just:

string mystring = "";
foo(ref mystring);

I wanted to call:

foo(ref new string('\0',0), 0); //such intuitive syntax

You couldn't do that whatever the type was - the problem isn't creating
a new empty string, it's that you don't have a variable in the above,
and you can't pass a plain value by reference - you have to pass the
variable.

From the C# spec:

<quote>
When a formal parameter is a reference parameter, the corresponding
argument in a method invocation must consist of the keyword ref
followed by a variable-reference (§12.3.3) of the same type as the
formal parameter.
private foo(ref string scratch, int k) {
do some things;
foo(scratch, k+1)
do something with what was accumulated in scratch;
}

The right way to do that is definitely to use a StringBuilder instead.
I've never used StringBuilder which is probably a better way except for
the month of study it would likely take to figure out MS wants it to be
used.

If it takes you a month to learn how to use StringBuilder, then you
should really consider a different hobby or line of work. There's a
very brief description of it at
http://www.wintellect.com/resources/tip/tiparchive.aspx?id=10
I thought my question was rather clear, "how do you make a new empty
string?"

But without any context, and certainly no mention of ref parameters.
It's very, very rare to really *need* a new empty string, and you don't
actually need one here. If you'd written some of the context in your
original post, we could have saved a lot of time.
All the answers until someone (thank-you) came up with new
String('\0',0) insisted that "" was an object rather than some static
item on the string table!

"" is a reference to an object, just as new String('\0', 0) is. They're
both references to strings, and all strings are immutable. You haven't
demonstrated any need for actually creating a *new* string object
rather than using String.Empty or "".
I guess bad code is that which is not dedicated to a WinForm.

I think you've misunderstood both the problem you're facing and the
answers.
 
Back
Top