These “cool” (but less well-known) things help make the code faster; it is easier to read and understand.
Welcome back to part 2 of the Amazing C# article. You can review part 1 here.
1. Optional Parameters
Many of you will not know what optional parameters are (I know it from C ++, but recently I know that C # also has =)). Assuming there are no optional parameters, we want to run the Add functions as follows:
Add(1, 2);
Add(1, 2, 3.5);
Add(1, 2, 3.5, "Hello");
Add(1, 2, true);
We need to overwrite the Add function overload 4 times.
public int Add(int num1, int num2)
public int Add(int num1, int num2, double num3)
public int Add(int num1, int num2, double num3, string num4)
public int Add(int num1, int num2, bool bol)
Extremely annoying and time-consuming, right? With optional parameters, we can write a function that takes all of the parameters and specify one of the parameters as optional. Otherwise, it will use the default value:
public int Add (int num1, int num2,
double num3 = 0, string num4 = "", bool bol = true)
// Add statement (1, 2, true) ;, because skip num3 and num4, we will call
Add (1, 2, bol: false);
// The following 2 statements will be equivalent.
// When we do not pass num3, num4, they will use the default value
Add (1, 2);
Add (1, 2, 0, "", true);
If you have learned C ++, it does not matter with this concept. As you can see, it saves us a lot of coding time.
2. Anonymous Type
As mentioned in Part 1, Anonymous Type is beneficial in many cases. Suppose we have 1 Student class with 10 properties.
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Name2 { get; set; }
public int Age2 { get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
public string Field5 { get; set; }
public string Field6 { get; set; }
}
In case we want to get 2 fields, Name and Age of Student, to serialize to JSON for brevity, we write the following code.
List <Student> students = new List <Student> ();
var stu = students.Select (st => new {Name = st.Name, Age = st.Age});
// Or more concisely
stu = students.Select (st => new {st.Name, st.Age});
The received Anonymous object will be an object with 2 properties: Name and Age. This object also implements the Equals () function so that we can compare these 2 objects easily. However, we also need to be careful with some cases of “equal but not equal.
var a = new {Name = "Hoang", Age = 10};
var b = new {Name = "Hoang", Age = 10};
Console.WriteLine (a == b); // True
// Be careful of the following cases
var c = new {Name = "Hoang", Age = 10};
var d = new {Name = "Hoang", Age = 10.2};
var e = new {Age = 10, Name = "Hoang",};
Console.WriteLine (c == d); // No compile, error
Console.WriteLine (c == e); // No compile, error
3. Tuple
A tuple is a rather “strange” concept; I first met this concept in Python, now I know it in C #. It can be understood that a tuple is a “clump” of many fields, similar to a class, but define faster and easier. For example:
var love = new Tuple<int>(1);
var lie = new Tuple<int, string>(1, "Why");
var lay = new Tuple<int, int, string>(1, 2, "Gay");
Console.WriteLine(lay.Item1 + " " + lay.Item2 + " " + lay.Item3);
// 1 2 Gay
Anonymous type has one drawback; that is, it is impossible to use the anonymous type as the return type or to pass parameters to a function.
public ??? GetStu () // How to return
{
List <Student> students = new List <Student> ();
var stu = students.Select (st => new {st.Name, st.Age});
return stu;
}
DoSomething (stu);
public void DoSomething (???); // How to pass in
but with Tuple:
public List<Tuple<string, int>> GetStu()
{
List<Student> students = new List<Student>();
var stu = students.Select(st => new Tuple<string, int>(st.Name, st.Age)).ToList();
return stu;
}
public void DoSomething( List<Tuple<string, int>> input);
DoSomething(stu);
You may ask: Why not create a new class? Why do you use an anonymous type with tuple? Please answer:
- There are some cases where we need to extract some fields; if we take a few fields we create a new class, the code will be quite redundant and meaningless.
- If we create a new class, we have to override Equals and GetHashCode if we need to compare. Anonymous types and tuples have automatically implemented this function for us.
4. String and little-known things
Surely all of us have used strings to draw headers, footers like this?
The code we used was:
string header = "";
for (int i = 0; i <80; i ++)
{
header + = "";
}
// The simpler way with string, you will be very surprised =))
string header = new string ('=', 80);
Similarly, when we have a list of strings, we want to add up all the list strings.
List <string> list = new List <string> {"1", "2", "3"};
string result = "";
foreach (var str in list)
{
result + = str + ",";
}
// Incredibly simple second time
string result = string.Join (",", list);
// More dominant when we join with non-string param
string result = string.Join (",", "Hello", 1, 2, 3.5); // Hello, 1, 2, 3.5
6. Initialize Collection (ToArray, ToList, ToDictionary, …)
When using Linq, after using Where, Select, … the return result is usually 1 IEnumerable, we can turn them into List or Array with available functions. ToList is the most used function:
List <Student> students = new List <Student> ();
IEnumerable <Student> stu = students.Where (st => st.Age> 0);
// Create list
List <Student> stuList = stu.ToList ();
// Create array
Student [] stuArray = stu.ToArray ();
// Create a dictionary, Key is Name, Value is Age
Dictionary <string, int> stuDic = stu.ToDictionary (t => t.Name, t => t.Age);
The article is the end. Because the article content is limited, in some parts, I only introduce the overview, not go into detail.
Parts like Linq, Anonymous Type, Delegate, … you could find on my personal page. .”