views:

526

answers:

10

Is there a reason for this? I am asking this because if you needed to use lots of empty char, then you get into the same situation as you would when you use lots of empty strings.

EDIT: Reason for this usage was this:

myString.Replace ('c', '')

So remove all instances of 'c's from myString.

+24  A: 

There's no such thing as an empty char. The closest you can get is '\0', the Unicode "null" character. Given that you can embed that within string literals or express it on its own very easily, why would you want a separate field for it? Equally, the "it's easy to confuse "" and " " arguments don't apply for '\0'.

If you could give an example of where you'd want to use it and why you think it would be better, that might help...

Jon Skeet
Isn't the \0 the 'end of the byte array'-character? Or am I confusing with something else?
Bertvan
Man, how can you write *exactly* the same first sentence? I need to start to learn to type faster
Philippe Leybaert
@Bertvan: Why would there be a *character* at the end of a *byte* array? It's used for "null terminated" strings though, yes.
Jon Skeet
@Bertvan That is true for C strings not for C# strings
Carlos Muñoz
damnit Jon, you beat me to it. :-)
George Stocker
Thanks, didn't realize you couldn't have an empty char. I ran into this when I was trying to replace all instances of say 'c' with '', so essentially getting rid of all 'c's in a string. Had to use the string overload of string.Replace.
Joan Venge
This speed is ridiculous. Finally, a question comes along I can actually answer and it has already been 'Skeeted
Callum Rogers
Char.MinValue is better than '\0'
Aliostad
@Jon @Carlos, yup, wasn't thinking that one true
Bertvan
@Aliostad: In what way? It's a heck of a lot uglier to ember in a string literal. Mind you, I don't use string.Empty either.
Jon Skeet
@Jon: added the usage details per your request.
Joan Venge
@Jon: Hi Jon. A big fan of yours, listened to your podcast it was great. On the subject, you get intellisence on Char.MinValue which I prefer. That is what constants (or static readonly)s are for - IMHO.
Aliostad
@Aliostad: Out of interest, if there was a similar field for `Int32.Zero`, would you use that instead of the literal 0? If not, what's the difference here?
Jon Skeet
@Aliostad: I disagree; constants are for values that have meaning. An empty string, dividing by 2, etc. have meaning that is fully evident by their usage. I don't need a constant for a null character or empty string any more than I need `const double ONE_HALF = .5`.
Adam Robinson
@Adam, @Jon -- what is the code for bell? Or backspace better, think think... Or maybe instead of thinking it is just better to write Char.Backspace? Another reason -- you say it is better to write '0' for terminator, instead, say Char.Terminator, however it is not -- it is too easy to make a typo (fully compiled, see above), but try to write Char.Termnator. There are enough reasons for me to avoid non-checkable, raw values (space missions failed because of stupid typos like that).
macias
@Macias: Except of course `Char.Backspace` doesn't exist, nor does `Char.Terminator`. For backspace I'd write `\b` - I'd forgotten about `\a` for bell, but I knew it was Unicode U+0007, so I'd write `\u0007`. If you know the number and want to make that obvious, the `\uxxxx` format is pretty clear IMO. Note that in this case using `Char.MinValue` requires you to a) know that you want character 0, b) know that `Char.MinValue` is 0. I'd argue that if you know the first point, then `\u0000` is a clear way of writing it, even if you don't know about `\0`.
Jon Skeet
@macias: Out of interest, have you introduced your own constant for backslash, or do you just write `\\` like everyone else? If not, what's the difference here? (One minor point to note: I *do* recommend that folks avoid the `\x....` escape sequence... that's horribly context-sensitive due to the length being variable.) I should point out that I can't remember the last time I needed to use `\0`, bell *or* backspace...
Jon Skeet
@Jon, as comment to you (disclaimer: sorry for obscenity, if any) -- \4758\7732\8575\47582\4757\1235\4857\4576... ;-) (btw. I didn't vote for MinChar, but for **constants**, and introducing new constants is not rocket-science).
macias
@macias: Constants in general, yes. I was never arguing against them. Constants in this case - no, IMO. Using literals and escaping in moderation is absolutely fine.
Jon Skeet
@Jon, of course I write "hello", not Char.H+Char.E+...but despise I sin (\*) writing "\n" it is bad (IMHO). If you put the software maintaince in perspective of decades (!), every tiny hole can cause serious damage. It is better to be precise and write +Char.Terminator every time, then once make a typo '0' and be very sorry later. Or I put it this way -- is there a purpose for producing code that is less manageable and weaker that it **could** be for almost free? (*) Seriously, after this discussion I will type constant for every \n from now on, howgh! ;-)
macias
+5  A: 

There's no such thing as an empty character. It always contains something. Even '\0' is a character.

Philippe Leybaert
+1 nice channeling of sir jon!
kenny
+13  A: 

A char, unlike a string, is a discrete thing with a fixed size. A string is really a container of chars.

So, Char.Empty doesn't really make sense in that context. If you have a char, it's not empty.

Joe
Exactly right. It makes sense to ask if a container is empty or not. It makes no sense to ask of a int or float or char is empty.
T.E.D.
+4  A: 

Use Char.MinValue which works the same as '\0'. But be careful it is not the same as Empty.String.

Aliostad
Thanks, haven't seen that before. Do you know if it work in myString.Replace('c', Char.MinValue)? I should give it a try.
Joan Venge
+3  A: 

the same reason there isn't an int.Empty. Containers can be empty. Scalar values cannot be. If you mean 0 (which is not empty), then use '\0'. If you mean null, then use null :)

tenfour
null is not possible as char is a ValueType. You'd have to use char? to be able to assign null to it.
Femaref
you chould make it nullable. see my answer
paquetp
Good point man.
Joan Venge
+3  A: 

A char is a value type, so its value cannot be null. (Unless it is wrapped in a Nullable container).

Since it can't be null, in contains some numeric code and each code is mapped to some character.

epotter
+8  A: 

You could use nullable chars.

char? c
paquetp
This allows ''? Or just null?
Joan Venge
I like that. +1
Aliostad
In your case, you could do this: myString.Replace("c", (c == null ? "" : c.ToString()))
paquetp
+5  A: 

Your sample

 myString.Replace ('c', '\0')

Won't remove any characters. It will just replace them with '\0' (EOS), with varying consequences.
Just use the string overload:

 myString.Replace ("c", "")
 myString.Replace ("c", string.Empty)  //for aesthetic reasons only
Henk Holterman
Thanks, what I had to use.
Joan Venge
+2  A: 

If you don't need the entire string, you can take advantage of the delayed execution:

public static class StringExtensions
{
    public static IEnumerable<char> RemoveChar(this IEnumerable<char> originalString, char removingChar)
    {
        return originalString.Where(@char => @char != removingChar);
    }
}

You can even combine multiple characters...

string veryLongText = "abcdefghijk...";

IEnumerable<char> firstFiveCharsWithoutCsAndDs = veryLongText
            .RemoveChar('c')
            .RemoveChar('d')
            .Take(5);

... and only the first 7 characters will be evaluated :)

EDIT: or, even better:

public static class StringExtensions
{
    public static IEnumerable<char> RemoveChars(this IEnumerable<char> originalString,
        params char[] removingChars)
    {
        return originalString.Except(removingChars);
    }
}

and its usage:

        var veryLongText = "abcdefghijk...";
        IEnumerable<char> firstFiveCharsWithoutCsAndDs = veryLongText
            .RemoveChars('c', 'd')
            .Take(5)
            .ToArray(); //to prevent multiple execution of "RemoveChars"
Notoriousxl
Genius example.
Joan Venge
@Joan: thanks... even if "Genius" it's a bit exaggerated :P (I don't know about its performances when removingChars will become a big array...)
Notoriousxl
Yesterday I forgot: pay attention on how you are using the result variable "firstFiveCharsWithoutCsAndDs". If you don't want to pass it to another "yield" method (like those of LINQ), call immediately a ".ToArray()" after the "Take(5)"... otherwise, the "RemoveChars + Take" chain will be executed every time you access the variable in a "traditional" fashion (for example, every you call a "Count()" on it, or when you traverse it in a foreach without "yield return")
Notoriousxl
A: 

How about BOM, the magical character Microsoft adds to start of files (at least XML)?

Arto Viitanen
The wording on Wikipedia here is quite unfortunate; the BOM is not a character in this context. And what is your question exactly? :)
bzlm