views:

522

answers:

5

Or, "am I doing it wrong"?

I am writing a small function that will return a string, quoted (as quoted-printable) if necessary, otherwise it returns it as is. A character is input into the function; the result is a string.

What I tried to do at first was:

private string QuotedChar(char ch) {
    if(ch < (char)128 && !char.IsWhiteSpace(ch))
        return(new string(ch));

    // ...
}

However, the compiler says CS0214, "Pointers and fixed size buffers may only be used in an unsafe context", when compiling that return statement. If I change the code to say instead:

private string QuotedChar(char ch) {
    if(ch < (char)128 && !char.IsWhiteSpace(ch))
        return(new string(new char[] { ch }));

    // ...
}

... it works just fine. However that seems rather pointless. I don't understand why it thinks I am trying to use a pointer or a fixed size buffer, since it's just a char. Am I missing something seriously silly, or is this a problem/bug?

FYI, this is Mono 2.0, not the Microsoft .NET Framework. I don't run Windows, so I don't have Microsoft's C# compiler to see if it does the same thing or not, which is why I wonder if it is a bug.

+7  A: 

Well, it's not a bug that it doesn't compile. There's no string constructor overload which takes a char. I suspect that Mono thought you meant the string(char*) constructor and tried that - leading to the error.

The simplest way of converting a char to a string is simply to call ToString() though:

private string QuotedChar(char ch) {
    if(ch < (char)128 && !char.IsWhiteSpace(ch))
        return ch.ToString()

    // ... 
}

The MS C# compiler guesses the same overload, but gives a different error message:

Test.cs(8,20): error CS1502: The best overloaded method match for 'string.String(char*)' has some invalid arguments
Test.cs(8,31): error CS1503: Argument '1': cannot convert from 'char' to 'char*'

Jon Skeet
A-ha. That works. Interesting; Mono showed a constructor that took a char, though I didn't find it in MSDN. I suspect you may be right re: the pointer, though, since it doesn't show 'char*' in the completion table in MonoDevelop. Thanks!
Michael Trausch
I suspect that's a MonoDevelop bug of just showing the possible overloads incorrectly.
Jon Skeet
It'd seem that way. I'll be filing a bug report just as soon as I build the tree from Subversion to confirm that it still exists there.
Michael Trausch
A: 

System.String does not have a constructor that takes a single char.

There are two possibilities:

String(Char*)

or

String(Char[])

This is why your second option works, and the first is thinking you are trying to pass in a pointer (unsafe).

Reed Copsey
A: 

There is no overload for new string() that takes a single char. What you're actually getting is the overload that takes a char*, meaning that it's expecting a pointer to a null-terminated character array, but pointers are only allowed when in an unsafe context.

Rather than creating an array, you could do new string(ch, 1)

Adam Robinson
A: 

I would change your "return new string(ch)" to "return ch.ToString()" string does not have a constructor that takes a single char. It DOES, however, have one that takes a char and a count.

you could go "new string(ch, 1 )" to create a string that contains 1 character, which would be what is in the ch variable.

Muad'Dib
+1  A: 

The same code compiled in .NET would give the error message that there was no overload for the string constructor that takes a char as parameter. The closest match is the one that takes a pointer to a char, so that may be why you get that error message in Mono.

You can use the overload that takes a char and a count:

return new String(ch, 1);

Or you can use the ToString method:

return ch.ToString();

Or the static ToString method:

return Char.ToString(ch);
Guffa