Introduction
Developers love strings. You might not agree with me, but most of the developers I’ve encountered like to play with strings. Now, the focus of this article is to focus more on the instance methods that the String class has. However; before diving into that section of this article, let’s give it a bit of an introduction by answering: “what is a string?”, types of strings, and how to define one.
What is a string?
In my opinion, we can say that a string is a collection or array-collection of read-only characters.
Many of us, think and believe its main use is for storing text values. Furthermore; whenever a string variable is updated, it is being recreated to a new instance.
When deciding to create a string, in a strict sense, you can put anything you want, and the compiler won’t complain.
Primarily, it starts and ends with either with a single quote or double quote.
Types of Strings
Basically, there are two types of string in C#.
Immutable strings
Strings that are once created cannot be modified. Hard to imagine? If you have some experience with strings you, probably questioned yourself: “How did that happen?” Basically, once a string is modified, it returns a new instance of the modified string value.
For instance, you have used the “csharp”.ToUpper() method. This method basically returns a new instance of a string that was modified. For that reason, you need to assign the return value to a certain string variable or else you won't get the expected result.
Mutable strings – the string content can be modified.
Ways to declare a string
Basically, we do have many ways to declare a string in our disposable.
See the example below, it focuses on declaring a string literal and declaring a string using a constructor.
- [TestMethod]
- public void Test_String_Define_New_String()
- {
- char[] characterCollection = new char[] { 'i', 'l','o','v', 'e','c','s','h','a','r','p' };
-
- string statement = new string(characterCollection);
-
- string newStatement = "ilovecsharp";
-
- Assert.AreEqual(statement, newStatement);
- }
Another common example of declaring a string is via
Console.ReadLine(). However; in our example, I'm using an MSTest project so I decided to mimic the console application inside the MsTest project.
- [TestMethod]
- public void Test_String_Define_New_String_Via_Console_ReadLine()
- {
- using (var writer = new StringWriter())
- {
- Console.SetOut(writer);
-
- Console.WriteLine("What is your favorite language?");
-
- using (var reader = new StringReader("C# language"))
- {
- Console.SetIn(reader);
-
- string fromInput = reader.ReadLine();
-
- Console.WriteLine($"Your favorite programming language is {fromInput}");
-
- string totalWrite = writer.ToString();
-
- string assumption = $"What is your favorite language?{Environment.NewLine}Your favorite programming language is {fromInput}{Environment.NewLine}";
-
- Assert.IsTrue(totalWrite.Equals(assumption));
- }
- }
- }
With the above example, don't be confused, just focus on the reader.ReadLine() method which acts like the Console.ReadLine() which waits for the user's input and processes the input as a new string instance.
Another thing to explore, remember that strings are an array of characters. Therefore; we can use an index to get the specific character. Let us see an example below.
- [TestMethod]
- public void Test_String_To_Get_Character_At_Specified_Position()
- {
- string newCountry = "";
-
- string country = "Philippines";
-
- for (int i = 0; i < country.Length; i++)
- {
- newCountry += country[i];
- }
-
- Assert.AreEqual(newCountry, country);
- }
C# String instance methods
a. CompareTo - this method throws an "ArgumentException" whenever you have supplied the wrong type. One reason is this method expects a string type for comparison. Let us see an example below.
- [TestMethod]
- [ExpectedException(typeof(ArgumentException))]
- public void Test_String_CompareTo_Method_Throws_ArgumentException()
- {
- int birthMonth = 3;
-
- string statement = "CSharp Rocks";
-
- statement.CompareTo(birthMonth);
-
-
- }
Being aware of the possible exception when this method is misused is nice to know. Let us dig into the usage. Comparing string instance to another string can be done by using this method. Just remember when this method returns zero it means the strings are equal. Let us see an example.
- [TestMethod]
- public void Test_String_CompareTo()
- {
- string[] programmingLanguages = new string[] { "C", "C++", "C#", "Java", "Python", null };
-
- string favoriteLanguage = "C#";
-
- foreach (var item in programmingLanguages)
- {
-
-
- int result = favoriteLanguage.CompareTo(item);
-
- switch (result)
- {
- case -1:
- Console.WriteLine($"Is {item} your favorite language?");
- break;
- case 0:
- Console.WriteLine("The comparison are equal");
- Console.WriteLine($"You got it. My favorite language is {item}");
- break;
- case 1:
- Console.WriteLine($"Is {(item == null ? "null" : item)} your favorite language?");
- break;
- }
-
- Assert.IsTrue((result >= -1 & result <= 1));
- }
- }
b. Equals - this methods throws a "NullReferenceException" whenever you have supplied a null instance value for comparison. Let us see an example below.
- [TestMethod]
- [ExpectedException(typeof(NullReferenceException))]
- public void Test_String_Equals_Method_Throws_NullReferenceException()
- {
- string laptop = null;
-
- laptop.Equals("DELL");
- }
So always be careful when checking for equality make sure your string is not null. Let us see how we can get it running properly.
- [TestMethod]
- public void Test_String_Equals_Method()
- {
- string[] countries = new string[] { "Philippines", "PHILIPPINES", "philippines", "USA", "usa", "Korea", "KOREA" };
-
- string country = "Philippines";
-
- foreach (var item in countries)
- {
- if (country.Equals(item))
- {
- Console.WriteLine($"{item} is equals {country}");
- }
- else
- {
- if (country.Equals(item, StringComparison.OrdinalIgnoreCase))
- {
- Console.WriteLine($"{item} is equals {country} case being ignored");
- }
- }
- }
- }
c. ToLower and ToUpper - these methods basically change the cases of your strings which in my opinion is pretty straight forward.
Let us see an example below for both of the methods.
- [TestMethod]
- public void Test_String_ToUpper()
- {
- string statement = "developers like to code people like to talk";
-
- statement.ToUpper();
-
- foreach (var item in statement.ToCharArray())
- {
- if (char.IsLower(item) & !char.IsWhiteSpace(item))
- {
- Console.WriteLine($"{item} is not in upper-case");
- Assert.IsTrue(char.IsLower(item));
- Assert.IsTrue(!char.IsWhiteSpace(item));
- }
- }
-
- string resultStatementToUpper = statement.ToUpper();
-
- foreach (var item in statement.ToCharArray())
- {
- if (char.IsUpper(item) & !char.IsWhiteSpace(item))
- {
- Console.WriteLine($"{item} is in upper-case");
- Assert.IsTrue(char.IsUpper(item));
- Assert.IsTrue(!char.IsWhiteSpace(item));
- }
- }
- }
-
- [TestMethod]
- public void Test_String_ToLower()
- {
- string statement = "DEVELOPERS LIKE TO CODE PEOPLE LIKE TO TALK";
-
- statement.ToLower();
-
- foreach (var item in statement.ToCharArray())
- {
- if (char.IsUpper(item) & !char.IsWhiteSpace(item))
- {
- Console.WriteLine($"{item} is not in upper-case");
- Assert.IsTrue(char.IsUpper(item));
- Assert.IsTrue(!char.IsWhiteSpace(item));
- }
- }
-
- string resultStatementToLower = statement.ToLower();
-
- foreach (var item in statement.ToCharArray())
- {
- if (char.IsLower(item) & !char.IsWhiteSpace(item))
- {
- Console.WriteLine($"{item} is in upper-case");
- Assert.IsTrue(char.IsLower(item));
- Assert.IsTrue(!char.IsWhiteSpace(item));
- }
- }
- }
Just a few points to mention about the example above. We have use the methods char.IsLower, char.IsUpper.
These 2 methods are convenient for the developer to check for the character's current case if lower or upper-case.
Lastly, the string method ToCharArray() converts the string literal to its character array representation, wherein you can iterate after getting the array values.
d. StartsWith and EndsWith - these methods actually check if the string starts/ends with a certain character. Again, we need to be aware of the exceptions thrown when the methods are misused.
Let us see an example below.
- [TestMethod]
- [ExpectedException(typeof(ArgumentNullException))]
- public void Test_String_EndsWith_Throws_ArgumentNullException()
- {
- string statement = "I didn't end with null";
-
- statement.EndsWith(null);
- }
-
- [TestMethod]
- [ExpectedException(typeof(ArgumentNullException))]
- public void Test_String_StartsWith_Method_Throws_ArgumentNullException()
- {
- string myParagraph = "Introduction to C# programmIng.";
-
- myParagraph.StartsWith(null);
- }
More examples are below for the usage of the two methods.
- [TestMethod]
- public void Test_String_EndsWith_Using_Default_StringComparison()
- {
- string[] vowels = new string[] { "a", "e", "i", "o", "u" };
-
- string statement = "I love .NET Framework. How about you";
-
- foreach (var item in vowels)
- {
- var result= statement.EndsWith(item);
-
- Assert.IsInstanceOfType(result, typeof(bool));
- }
- }
-
- [TestMethod]
- public void Test_String_EndsWith_Passing_Different_StringComparison()
- {
- string[] vowels = new string[] { "a", "e", "i", "o", "u" };
-
- string statement = "I love .NET Framework. How about you".ToUpper();
-
- foreach (var item in vowels)
- {
- var result = statement.EndsWith(item, StringComparison.CurrentCultureIgnoreCase);
-
- if (result) Console.WriteLine($"Yes it ends with {item}");
- }
- }
-
- [TestMethod]
- public void Test_String_StartsWith_Method()
- {
- string myParagraph = "Introduction to C# programmIng.";
-
- string[] startsWithTheWord = new string[] { "Introduction", "introduction" };
-
- foreach (var word in startsWithTheWord)
- {
- var result = myParagraph.StartsWith(word);
-
- Assert.IsInstanceOfType(result, typeof(bool));
-
- var resultIgnoredCase = myParagraph.StartsWith(word, StringComparison.OrdinalIgnoreCase);
-
- Assert.IsInstanceOfType(resultIgnoredCase, typeof(bool));
- }
- }
e. TrimStart, TrimEnd, and Trim - the main functionality of these methods is to trim strings. Furthermore, you need to shorten strings where? Is it the head? The tail? Or both? The TrimStart trims the head of the string, the TrimEnd trims the tail of the string and the Trim trims the entire string. Let us see a basic example below.
- [TestMethod]
- public void Test_String_TrimStart()
- {
- string paragraph = " Hello World ";
-
- string trimTheHead = paragraph.TrimStart();
- Assert.IsTrue(trimTheHead == "Hello World ");
-
- string trimTheTail = paragraph.TrimEnd();
- Assert.IsTrue(trimTheTail == " Hello World");
-
- string trimHeadAndTail = paragraph.Trim();
- Assert.IsTrue(trimHeadAndTail == "Hello World");
- }
f. IndexOf and LastIndexOf - The main function of these methods gets the specific position index of the string character. IndexOf focuses on the first instance and LastIndexOf focuses on the last instance of the character inside the string.
Again, being a bit defensive doesn't hurt. Let us see the exceptions being thrown by these methods when misused.
- [TestMethod]
- [ExpectedException(typeof(ArgumentOutOfRangeException))]
- public void Test_String_IndexOf_Method_Throws_Argument_Exception()
- {
- string myParagraph = "Introduction to C# programmIng.";
-
- int length = myParagraph.Length;
-
- int index = -1;
-
- index = myParagraph.IndexOf('a', (length + 1));
- }
-
- [TestMethod]
- [ExpectedException(typeof(ArgumentOutOfRangeException))]
- public void Test_String_LastIndexOf_Method_Throws_Argument_Exception()
- {
- string myParagraph = "Introduction to C# programmIng.";
-
- int length = myParagraph.Length;
-
- int index = -1;
-
- index = myParagraph.LastIndexOf('I', (length + 1));
- }
More examples for using both methods.
- [TestMethod]
- public void Test_String_IndexOf_And_LastIndexOf_Method()
- {
- string[] vowels = new string[] { "a", "e", "i", "o", "u" };
-
- string[] vowelsUpper = new string[] { "A", "E", "I", "O", "U" };
-
- string myParagraph = "Introduction to C# programmIng.";
-
- int index = -1;
-
- foreach (var item in vowels)
- {
- index = myParagraph.IndexOf(item);
-
- if (index != -1)
- {
- string result = myParagraph.ReplaceIndexWith(index, item.ToUpper());
-
- Console.WriteLine(result);
- }
- }
-
- foreach (var item in vowelsUpper)
- {
- index = myParagraph.LastIndexOf(item);
-
- if (index != -1)
- {
- string result = myParagraph.ReplaceIndexWith(index, item.ToLower());
-
- Console.WriteLine(result);
- }
- }
- }
A point on the above example. The "ReplaceIndexWith" is an extension method that replaces the index with a new character. More on that later because we are going to discuss the used methods of the "ReplaceIndexWith" which are Insert and Remove methods.
g. Insert and Remove - These methods help developers to insert and remove characters within a string. These methods are used inside the "ReplaceIndexWith" so let us see the full example below.
- public static string ReplaceIndexWith(this string value, int index, string replacement)
- {
- string result = value;
-
- result = value.Insert((index + 1), replacement);
- result = result.Remove(index, 1);
-
- return result;
- }
h. Replace and Contains - These methods do what is says from their method names. Replace actually replaces the string to a new one that you have passed. Contains method checks whether the string contains a specific element.
- [TestMethod]
- public void Test_String_Replace_And_Contains()
- {
- string[] heroes = new string[] { "Batman", "Superman", "Robin" };
-
- foreach (var item in heroes)
- {
- if (item.Contains("n"))
- {
- string newHeroName = item.Replace("n", "x");
-
- Assert.IsTrue(newHeroName.Contains("x"));
- }
- }
- }
i. Split - This method turns the string into an array of strings, but you need to provide the separator. Let us see an example below.
- [TestMethod]
- public void Test_String_Split_Method()
- {
- string countries = "Philippines,Korea,Japan,Indonesia,Australia";
-
- var arrayOfCountries = countries.Split(',');
-
- Assert.IsInstanceOfType(arrayOfCountries, typeof(string[]));
- }
Remarks
We have seen, how we can use the instance methods of string class.
Of course, weren't able to tackle everything but I'm hoping this will help others.
That's all, for now, fellow developers.
Until next time, happy programming!