Is there a way to concat string with char as a const? - c#

If I try
const char NoChar = (char)8470; //№
const char TmChar = (char)8482; //™
const string IdDisplayName = "Clements" + TmChar + ' ' + NoChar;
it will throw a compile error:
The expression being assigned to '{0}' must be constant
As far as I understand, this error occurs because when a char is because the string concatenation operator (+) internally calls ToString on the concatenated object.
My question is if there is a way (unmanaged?) to do it.
I need to pass that constant as an attribute and it should be generated on client.
The uglier workaround (will see what's uglier based on your answers...) is to subclass that attribute (which is sealed, will have to make some decompilation and copy-paste work) and embedding it as a non-const will be possible.

You're allowed to specify unicode character values directly in a string via the \u escape. So const string IdDisplayName = "Clements\u2122 \u2116"; should get you what you want.

I assume that simply:
const string NoChar = "\x2116"; //№ - Unicode char 8470
const string TmChar = "\x2122"; //™ - Unicode char 8482
const string IdDisplayName = "Clements" + TmChar + " " + NoChar;
Is unacceptable?

Related

Concatenating a char with an int and a string does odd things

I was coding and needed to build up a file name. I wanted to separate the parts of the file names by an _.
I figured that since I only wanted to add on char in I could use '_'.
int id = 125;
string testWithChar = id + '_' + "Something";
Console.WriteLine(testWithChar);
But when I do I get this:
220Something
Kind of odd.
But if I do it right:
int id = 125;
string testWithString = id + "_" + "Something";
Console.WriteLine(testWithString);
I get the expected output:
125_Something
But I am curious. What is really happening in the first one to give me a different number?
The reason is, C# is considering the char as it's unicode value, and thus the addition between them does not add strings, but integers.
_ in ascii is 95, and thus
int id = 125;
string testWithChar = id + '_' + "Something";
is the equivallent of:
string testWithChar = 125 + 95 + "Something";
In contrast, when you add "_", the addition is done between a string and an integer - and the operator just appends the string to it.
The int value of a char is its place in the ASCII table. '_' is at place 95
When you add an integer to another numeric type, you end up with the result of the addition, rather than the concatenation. In this case, char is a numeric value, so 125 + 95 (value of '_') concatenated with your string gives you 220_Something.
I'd create the string as string.Format("{0}_{1}", id, "Something") instead, particularly as your final string gets more complicated.
The int value is replaced with its ASCII value of 95.
Using string formatting is the most safe way:
Console.WriteLine("{0}_Something", id);

What is .NET string structure and how .NET take care to store and retrieve it's string structure?

Let's face following code :
string a = "This is not a long string!";
string b = "Another string";
b = "This is" + " not a long " + "string" + "!";
Console.WriteLine(object.ReferenceEquals(a, b)); //True !
string c = "This is" + " not a long " + "string" + '!';
Console.WriteLine(object.ReferenceEquals(a, c)); //False
The only reason I see is that .NET has optimized variables to take less space.
Does .NET store strings with zero terminated[null] or string length ?
I mean when I write following code is it possible to lose the part after the null char if .NET run optimization against the string ?
string Waaaa = "This is not \0a long string!";
Strings in .NET are in essence character arrays - char[] (where char is a representation of a UTF-16 character). They are not C strings - they are not null terminated.
What you see is the result of string interning - any string literal will get interned (and the compiler is smart enough to know to convert concatenated strings to a single literal).
Your Waaaa variable will be exactly what you have posted - with a null character in the middle.

How to change 1 char in the string?

I have this code:
string str = "valta is the best place in the World";
I need to replace the first symbol. When I try this:
str[0] = 'M';
I received an error. How can I do this?
Strings are immutable, meaning you can't change a character. Instead, you create new strings.
What you are asking can be done several ways. The most appropriate solution will vary depending on the nature of the changes you are making to the original string. Are you changing only one character? Do you need to insert/delete/append?
Here are a couple ways to create a new string from an existing string, but having a different first character:
str = 'M' + str.Remove(0, 1);
str = 'M' + str.Substring(1);
Above, the new string is assigned to the original variable, str.
I'd like to add that the answers from others demonstrating StringBuilder are also very appropriate. I wouldn't instantiate a StringBuilder to change one character, but if many changes are needed StringBuilder is a better solution than my examples which create a temporary new string in the process. StringBuilder provides a mutable object that allows many changes and/or append operations. Once you are done making changes, an immutable string is created from the StringBuilder with the .ToString() method. You can continue to make changes on the StringBuilder object and create more new strings, as needed, using .ToString().
I suggest you to use StringBuilder class for it and than parse it to string if you need.
System.Text.StringBuilder strBuilder = new System.Text.StringBuilder("valta is the best place in the World");
strBuilder[0] = 'M';
string str=strBuilder.ToString();
You can't change string's characters in this way, because in C# string isn't dynamic and is immutable and it's chars are readonly. For make sure in it try to use methods of string, for example, if you do str.ToLower() it makes new string and your previous string doesn't change.
Strings are immutable. You can use the string builder class to help!:
string str = "valta is the best place in the World";
StringBuilder strB = new StringBuilder(str);
strB[0] = 'M';
While it does not answer the OP's question precisely, depending on what you're doing it might be a good solution. Below is going to solve my problem.
Let's say that you have to do a lot of individual manipulation of various characters in a string. Instead of using a string the whole time use a char[] array while you're doing the manipulation. Because you can do this:
char[] array = "valta is the best place in the World".ToCharArray();
Then manipulate to your hearts content as much as you need...
array[0] = "M";
Then convert it to a string once you're done and need to use it as a string:
string str = new string(array);
Merged Chuck Norris's answer w/ Paulo Mendonça's using extensions methods:
/// <summary>
/// Replace a string char at index with another char
/// </summary>
/// <param name="text">string to be replaced</param>
/// <param name="index">position of the char to be replaced</param>
/// <param name="c">replacement char</param>
public static string ReplaceAtIndex(this string text, int index, char c)
{
var stringBuilder = new StringBuilder(text);
stringBuilder[index] = c;
return stringBuilder.ToString();
}
I made a Method to do this
string test = "Paul";
test = ReplaceAtIndex(0, 'M', test);
// (...)
static string ReplaceAtIndex(int i, char value, string word)
{
char[] letters = word.ToCharArray();
letters[i] = value;
return string.Join("", letters);
}
str = "M" + str.Substring(1);
If you'll do several such changes use a StringBuilder or a char[].
(The threshold of when StringBuilder becomes quicker is after about 5 concatenations or substrings, but note that grouped concatenations of a + "b" + c + d + "e" + f are done in a single call and compile-type concatenations of "a" + "b" + "c" don't require a call at all).
It may seem that having to do this is horribly inefficient, but the fact that strings can't be changes allows for lots of efficiency gains and other advantages such as mentioned at Why .NET String is immutable?
I found a solution in unsafe context:
string str = "gg"; char c = 'H'; int index = 1;
fixed (char* arr = str) arr[index] = 'H';
Console.WriteLine(str);
It's so simple.
And in safe context:
string str = "gg"; char c = 'H'; int index = 1;
GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned);
IntPtr arrAddress = handle.AddrOfPinnedObject();
Marshal.WriteInt16(arrAddress + index * sizeof(char), c);
handle.Free();
Console.WriteLine(str);
If speed is important, then you can do this:
String strValue = "$Some String Here!";
strValue = strValue.Remove(0, 1).Insert(0, "*");
This way, you don't really reconstruct the string, you keep the original object and just removing the first character and inserting a new one.
I usually approach it like this:
char[] c = text.ToCharArray();
for (i=0; i<c.Length; i++)
{
if (c[i]>'9' || c[i]<'0') // use any rules of your choice
{
c[i]=' '; // put in any character you like
}
}
// the new string can have the same name, or a new variable
String text=new string(c);
Can also be done using C# 8 ranges:
str = "M" + str[1..];
or + string interpolation:
str = $"M{str[1..]}";

String Concat using constants - performance

Assume I have the following string constants:
const string constString1 = "Const String 1";
const string constString2 = "Const String 2";
const string constString3 = "Const String 3";
const string constString4 = "Const String 4";
Now I can append the strings in two ways:
Option1:
string resultString = constString1 + constString2 + constString3 + constString4;
Option2:
string resultString = string.Format("{0}{1}{2}{3}",constString1,constString2,constString3,constString4);
Internally string.Format uses StringBuilder.AppendFormat. Now given the fact that I am appending constant strings, which of the options (option1 or option 2) is better with respect to performance and/or memory?
The first one will be done by the compiler (at least the Microsoft C# Compiler) (in the same way that the compiler does 1+2), the second one must be done at runtime. So clearly the first one is faster.
As an added benefit, in the first one the string is internalized, in the second one it isn't.
And String.Format is quite slow :-) (read this
http://msmvps.com/blogs/jon_skeet/archive/2008/10/06/formatting-strings.aspx). NOT "slow enough to be a problem", UNLESS all your program do all the day is format strings (MILLIONS of them, not TENS). Then you could probably to it faster Appending them to a StringBuilder.
The first variant will be best, but only when you are using constant strings.
There are two compilator optimizations (from the C# compiler, not the JIT compiler) that are in effect here. Lets take one example of a program
const string A = "Hello ";
const string B = "World";
...
string test = A + B;
First optimization is constant propagation that will change your code basically into this:
string test = "Hello " + "World";
Then a concatenation of literal strings (as they are now, due to the first optimization) optimization will kick in and change it to
string test = "Hello World";
So if you write any variants of the program shown above, the actual IL will be the same (or at least very similar) due to the optimizations done by the C# compiler.

how can I convert a char to a char* in c#?

how can I convert a char to a char* in c#?
I'm initializeing a String object like this:
String test=new String('c');
and I'm getting this error:
Argument '1': cannot convert from 'char' to 'char*'
That is a bit of a strange way to initialize a string, if you know beforehand what you want to store in it.
You can simply use:
String test="c";
If you have a specific need to convert a char variable to a string, you can use the built in ToString() function:
String test = myCharVariable.ToString();
unsafe
{
char c = 'c';
char *ch = &c;
}
Your example has a String and a compile error from using one of the String constructor overloads, so I'm guessing you really just want an array of chars, aka a String and maybe not a char*.
In which case:
char c = 'c';
string s = c.ToString(); // or...
string s1 = "" +c;
Also available:
unsafe
{
char c = 'c';
char* ch = &c;
string s1 = new string(ch);
string s2 = new string(c, 0);
}
string myString1 = new string(new char[] {'a'});
string myString2 = 'a'.ToString();
string myString3 = "a";
string myString4 = new string('a', 1);
unsafe {
char a = 'a';
string myString5 = new string(&a);
}
There is no overload of the public constructor for String that accepts a single char as a parameter. The closest match is
public String(char c, int count)
which creates a new String that repeats the char c count times. Thus, you could say
string s = new string('c', 1);
There are other options. There is a public constructor of String that accepts a char[] as a parameter:
public String(char[] value)
This will create a String that is initialized with the Unicode characters in value. Thus you could say
char c = 'c';
string s = new String(new char[] { c });
Another option is to say
char c = 'c'
string s = c.ToString();
But the most straightforward approach that most will expect to see is
string s = "c";
As for converting a char to a char * you can not safely do this. If you want to use the overload of the public constructor for String that accepts a char * as a parameter, you could do this:
unsafe {
char c = 'c';
char *p = &c;
string s = new string(p);
}
Can't hurt to have yet another answer:
string test = string.Empty + 'c';
The String class has many constructors, if all you're after is to create a string containing one character, you can use the following:
String test = new String(new char[] { 'c' });
If you are hard coding it, is there a reason you cant just use:
String test = "c";
How about:
var test = 'c'.ToString()
When using a char in the String constructor, you should also give a count parameter to specify how many times that character should be added to the string:
String test=new String('c', 1);
See also here.
use
String test("Something");
String test = new String(new char[]{'c'});
The easiest way to do this conversion from your example is just change the type of quotes you are using from single quotes
String test = new String('c');
to double quotes and remove the constructor call:
String test = "c";
char c = 'R';
char *pc = &c;
Using single quotes (as in your question: 'c') means that you are creating a char. Using double quotes, e.g. "c", means you creating a string. These are not interchangable types in c#.
A char*, as you might be aware, is how strings are represented in c++ to some extent, and c# supports some of the conventions of c++. This means that a char* can easily (for the programmer at least) be converted to a string in c#. Unfortunately a char is not inherently a char*, so the same cannot be done.

Categories