Csharp

C# Get started

hello guys, follow me and let’s studying the C#.

  • Commercial experience of software development in C#
  • Experience with source code version control such as Git
  • Experience with software development tools such as Visual Studio, JIRA, MSBuild, Jenkins
  • Experience with unit test frameworks such as NUnit or MSTest
  • Experience designing user interfaces. (Exposure to DevExpress an advantage).
  • Exposure to Iterative or Agile development methodologies (Scrum / Kanban)
  • Understanding of OOP
  • Understanding of SOLID

Chapter1: Basic

  • using: The keyword is used to include the System namespace in the program. A program usually has multiple using statements.
  • namespace: which contains different classes.
  • class: declariation of the class.
  • Main: Is the entry point for all C# programs. What does the class do when executed
  • Formatted output aka interpolation:Console.WriteLine($“Hello World! The counter is {counter}“); By using $ dollar symbol.

Here are a few things to note:

  • C# is case sensitive.
  • All statements and expressions must start with a semicolon (;). The end.
  • Execution of the program starts with the Main method.
  • Unlike Java, the file name can be different from the name of the class.

Numbers and Math in C#: Int,float,double,decimal,string..

1
2
3
4
5
6
7
8
int minVal = int.MinValue; // -2147483648
int maxVal = int.MaxValue; // 2147483647

double min = double.MinValue // -1.79769313486232E+308
double max = double.MaxValue // 1.79769313486232E+308

decimal min = decimal.MinValue; //-79228162514264337593543950335
decimal max = decimal.MaxValue; // 79228162514264337593543950335

The decimal type has a smaller range but greater precision than double.

The M suffix on the numbers is how you indicate that a constant should use the decimal type. For example:

1
2
3
decimal c = 1.0M;
decimal d = 3.0M;
Console.WriteLine(c / d);

Arrays:

1
2
3
4
5
6
7
8
9
// 定义一个整型数组,长度为3
int[] nums = new int[3];

// 定义一个字符串数组,长度为4,初始化数组元素
string[] names = new string[] { "Tom", "Jerry", "Alice", "Bob" };

// 使用 var 关键字定义数组
var scores = new int[] { 90, 80, 95, 85, 70 };

以上示例中,第一个定义创建了一个长度为 3 的整型数组,数组中的元素初始值为 0;第二个定义创建了一个长度为 4 的字符串数组,并初始化了每个元素的值;第三个定义使用 var 关键字根据初始化值推断出数组的类型,并创建了一个长度为 5 的整型数组

 Common Math function

  • Math.Abs: Returns the absolute value of a number.
  • Math.Ceiling: Rounds up a number and returns the smallest integer greater than or equal to that number.
  • Math.Floor: Rounds down a number and returns the largest integer less than or equal to the number.
  • Math.Max: Returns the maximum of two numbers.
  • Math.Min: Returns the minimum of two numbers.
  • Math.Pow: Returns the specified power of a number.
  • Math.Round: Round to the nearest whole number or number of specified decimal places.
  • Math.Sqrt: Returns the square root of a number.
  • Math.Log: Returns the natural log base e of a number.
  • Math.Exp: Returns e to the specified power.
  • Math.Truncate: Truncates a number into its integer part.

Chapter2. if/else/loop

1. if statement

bool carries true and false. which is different from java

1
2
3
4
5
6
7
if(condition){
execution when condition is true
}

else{
execution when condition is false
}

Logical AND Operator:&&

Logical OR Operator:||

Logical NOT Operator: !

Equality Operator: ==

2. loop

  1. while loop

    same with java

    1
    2
    3
    4
    5
    6
    int counter = 0;
    while (counter < 10)
    {
    Console.WriteLine($"Hello World! The counter is {counter}");
    counter++;
    }
  2. do while

    same with java

    1
    2
    3
    4
    5
    6
    int counter = 0;
    do
    {
    Console.WriteLine($"Hello World! The counter is {counter}");
    counter++;
    } while (counter < 10);
  3. for loop

​ Same with java

1
2
3
4
for (int counter = 0; counter < 10; counter++)
{
Console.WriteLine($"Hello World! The counter is {counter}");
}

(for initializer;for condition;for iterator) same with java

Nested for loop which can be used to create matrix, e.g:

1
2
3
4
5
6
7
for (int row = 1; row < 11; row++)
{
for (char column = 'a'; column < 'k'; column++)
{
Console.WriteLine($"The cell is ({row}, {column})");
}
}

Chapter3. Lists collection

Example:

1
2
3
4
5
var names = new List<string> { "Joshua", "Ana", "Felipe" };
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
  • You specify the type of the elements between the angle brackets, <>.
  • One important aspect of this List type is that it can grow or shrink, enabling you to add or remove elements.
1
2
3
4
5
6
7
8
9
var names = new List<string> { "Joshua", "Ana", "Felipe" };
Console.WriteLine();
names.Add("Joshua");
names.Add("Bill");
names.RemoveAll(name=>name=="Joshua");
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}

RemoveAll method is different from that in Java. It is provided by list

1
public int RemoveAll(Predicate<T> match);
  • list allows you reference the individual items by index directly which is different from java=>”list.get()”.

  • list also provides Count method which allows you to count the numbers of elements in the list. xxx.Count

  • list provides you a IndexOf method which allows you to find the index of the specific element.

  • The items in your list can be sorted as well. The Sort method sorts all the items in the list in their normal order (alphabetically for strings). Add this code and run again: Quite similar with the Collection.sort();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//print fibonacci numbers

var fibonacciNumbers = new List<int> {1, 1};

while (fibonacciNumbers.Count < 20)
{
var previous = fibonacciNumbers[fibonacciNumbers.Count - 1];
var previous2 = fibonacciNumbers[fibonacciNumbers.Count - 2];

fibonacciNumbers.Add(previous + previous2);
}
foreach(var item in fibonacciNumbers)
{
Console.WriteLine(item);
}

Fundamentals.

1. Program Structure.

1. Overview

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// A skeleton of a C# program
using System;

// Your program starts here:
Console.WriteLine("Hello world!");

namespace YourNamespace
{
class YourClass
{
}

struct YourStruct
{
}

interface IYourInterface
{
}

delegate int YourDelegate();

enum YourEnum
{
}

namespace YourNestedNamespace
{
struct YourStruct
{
}
}
}

The preceding example uses top-level statements for the program’s entry point. This feature was added in C# 9. Prior to C# 9, the entry point was a static method named Main, as shown in the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

// A skeleton of a C# program
using System;
namespace YourNamespace
{
class YourClass
{
}

struct YourStruct
{
}

interface IYourInterface
{
}

delegate int YourDelegate();

enum YourEnum
{
}

namespace YourNestedNamespace
{
struct YourStruct
{
}
}

class Program
{
static void Main(string[] args)
{
//Your program starts here...
Console.WriteLine("Hello world!");
}
}
}

Prefix of the c# file is .cs.

2. Main method

The Main method is the entry point of a C# application. (Libraries and services do not require a Main method as an entry point.) When the application is started, the Main method is the first method that is invoked.

There can only be one entry point in a C# program. If you have more than one class that has a Main method, you must compile your program with the StartupObject compiler option to specify which Main method to use as the entry point. For more information, see StartupObject (C# Compiler Options).

Starting in C# 9, you can omit the Main method, and write C# statements as if they were in the Main method (this is similar with Python), as in the following example:

1
2
3
4
5
6
7
using System.Text;

StringBuilder builder = new();
builder.AppendLine("Hello");
builder.AppendLine("World!");

Console.WriteLine(builder.ToString());

For information about how to write application code with an implicit entry point method, see Top-level statements.

  • The Main method is the entry point of an executable program; it is where the program control starts and ends.
  • Main is declared inside a class or struct. Main must be static and it need not be public. (In the earlier example, it receives the default access of private.) The enclosing class or struct is not required to be static.
  • Main can either have a void, int, Task, or Task<int> return type.
  • If and only if Main returns a Task or Task<int>, the declaration of Main may include the async modifier. This specifically excludes an async void Main method.
  • The Main method can be declared with or without a string[] parameter that contains command-line arguments. When using Visual Studio to create Windows applications, you can add the parameter manually or else use the GetCommandLineArgs() method to obtain the command-line arguments. Parameters are read as zero-indexed command-line arguments. Unlike C and C++, the name of the program is not treated as the first command-line argument in the args array, but it is the first element of the GetCommandLineArgs() method.

Valid main declariation:

1
2
3
4
5
6
7
8
public static void Main() { }
public static int Main() { }
public static void Main(string[] args) { }
public static int Main(string[] args) { }
public static async Task Main() { }
public static async Task<int> Main() { }
public static async Task Main(string[] args) { }
public static async Task<int> Main(string[] args) { }

The preceding examples all use the public accessor modifier. That’s typical, but not required. (which means they can be private).

The addition of async and Task, Task<int> return types simplifies program code when console applications need to start and await asynchronous operations in Main

Main() return values:

You can return an int from the Main method by defining the method in one of the following ways:

Main method code Main signature
No use of args or await static int Main()
Uses args, no use of await static int Main(string[] args)
No use of args, uses await static async Task<int> Main()
Uses args and await static async Task<int> Main(string[] args)

If the return value from Main is not used, returning void or Task allows for slightly simpler code.

Main method code Main signature
No use of args or await static void Main()
Uses args, no use of await static void Main(string[] args)
No use of args, uses await static async Task Main()
Uses args and await static async Task Main(string[] args)

However, returning int or Task<int> enables the program to communicate status information to other programs or scripts that invoke the executable file.

The following example shows how the exit code for the process can be accessed.

This example uses .NET Core command-line tools. If you are unfamiliar with .NET Core command-line tools, you can learn about them in this get-started article.

Create a new application by running dotnet new console. Modify the Main method in Program.cs as follows:

1
2
3
4
5
6
7
8
9
// Save this program as MainReturnValTest.cs.
class MainReturnValTest
{
static int Main()
{
//...
return 0;
}
}

When a program is executed in Windows OS, any value returned from the Main function is stored in an environment variable. This environment variable can be retrieved using ERRORLEVEL from a batch file, or $LastExitCode from PowerShell.

You can build the application using the dotnet CLI dotnet build command.

Next, create a PowerShell script to run the application and display the result. Paste the following code into a text file and save it as test.ps1 in the folder that contains the project. Run the PowerShell script by typing test.ps1 at the PowerShell prompt.

Because the code returns zero, the batch file will report success. However, if you change MainReturnValTest.cs to return a non-zero value and then recompile the program, subsequent execution of the PowerShell script will report failure.

1
2
3
4
5
6
7
8
dotnet run
if ($LastExitCode -eq 0) {
Write-Host "Execution succeeded"
} else
{
Write-Host "Execution Failed"
}
Write-Host "Return value = " $LastExitCode
1
2
Execution succeeded
Return value = 0

Async Main return values

When you declare an async return value for Main, the compiler generates the boilerplate code for calling asynchronous methods in Main. If you don’t specify the async keyword, you need to write that code yourself, as shown in the following example. The code in the example ensures that your program runs until the asynchronous operation is completed:

1
2
3
4
5
6
7
8
9
10
public static void Main()
{
AsyncConsoleWork().GetAwaiter().GetResult();
}

private static async Task<int> AsyncConsoleWork()
{
// Main body here
return 0;
}

This boilerplate code can be replaced by:

1
2
3
4
static async Task<int> Main(string[] args)
{
return await AsyncConsoleWork();
}

An advantage of declaring Main as async is that the compiler always generates the correct code.

When the application entry point returns a Task or Task<int>, the compiler generates a new entry point that calls the entry point method declared in the application code. Assuming that this entry point is called $GeneratedMain, the compiler generates the following code for these entry points:

  • static Task Main() results in the compiler emitting the equivalent of private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task Main(string[]) results in the compiler emitting the equivalent of private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
  • static Task<int> Main() results in the compiler emitting the equivalent of private static int $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task<int> Main(string[]) results in the compiler emitting the equivalent of private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();

Noted: If the examples used async modifier on the Main method, the compiler would generate the same code.

Command-Line Arguments

You can send arguments to the Main method by defining the method in one of the following ways:

Main method code Main signature
No return value, no use of await static void Main(string[] args)
Return value, no use of await static int Main(string[] args)
No return value, uses await static async Task Main(string[] args)
Return value, uses await static async Task<int> Main(string[] args)

If the arguments are not used, you can omit args from the method signature for slightly simpler code:

Main method code Main signature
No return value, no use of await static void Main()
Return value, no use of await static int Main()
No return value, uses await static async Task Main()
Return value, uses await static async Task<int> Main()

Note

You can also use Environment.CommandLine or Environment.GetCommandLineArgs to access the command-line arguments from any point in a console or Windows Forms application. To enable command-line arguments in the Main method signature in a Windows Forms application, you must manually modify the signature of Main. The code generated by the Windows Forms designer creates Main without an input parameter.

The parameter of the Main method is a String array that represents the command-line arguments. Usually you determine whether arguments exist by testing the Length property, for example:

C#Copy

1
2
3
4
5
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
return 1;
}

Tip

The args array can’t be null. So, it’s safe to access the Length property without null checking.

You can also convert the string arguments to numeric types by using the Convert class or the Parse method. For example, the following statement converts the string to a long number by using the Parse method:

C#Copy

1
long num = Int64.Parse(args[0]);

It is also possible to use the C# type long, which aliases Int64:

C#Copy

1
long num = long.Parse(args[0]);

You can also use the Convert class method ToInt64 to do the same thing:

C#Copy

1
long num = Convert.ToInt64(s);

For more information, see Parse and Convert.

The following example shows how to use command-line arguments in a console application. The application takes one argument at run time, converts the argument to an integer, and calculates the factorial of the number. If no arguments are supplied, the application issues a message that explains the correct usage of the program.

To compile and run the application from a command prompt, follow these steps:

  1. Paste the following code into any text editor, and then save the file as a text file with the name Factorial.cs.

    C#Copy

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    public class Functions
    {
    public static long Factorial(int n)
    {
    // Test for invalid input.
    if ((n < 0) || (n > 20))
    {
    return -1;
    }

    // Calculate the factorial iteratively rather than recursively.
    long tempResult = 1;
    for (int i = 1; i <= n; i++)
    {
    tempResult *= i;
    }
    return tempResult;
    }
    }

    class MainClass
    {
    static int Main(string[] args)
    {
    // Test if input arguments were supplied.
    if (args.Length == 0)
    {
    Console.WriteLine("Please enter a numeric argument.");
    Console.WriteLine("Usage: Factorial <num>");
    return 1;
    }

    // Try to convert the input arguments to numbers. This will throw
    // an exception if the argument is not a number.
    // num = int.Parse(args[0]);
    int num;
    bool test = int.TryParse(args[0], out num);
    if (!test)
    {
    Console.WriteLine("Please enter a numeric argument.");
    Console.WriteLine("Usage: Factorial <num>");
    return 1;
    }

    // Calculate factorial.
    long result = Functions.Factorial(num);

    // Print result.
    if (result == -1)
    Console.WriteLine("Input must be >= 0 and <= 20.");
    else
    Console.WriteLine($"The Factorial of {num} is {result}.");

    return 0;
    }
    }
    // If 3 is entered on command line, the
    // output reads: The factorial of 3 is 6.
  2. From the Start screen or Start menu, open a Visual Studio Developer Command Prompt window, and then navigate to the folder that contains the file that you created.

  3. Enter the following command to compile the application.

    dotnet build

    If your application has no compilation errors, an executable file that’s named Factorial.exe is created.

  4. Enter the following command to calculate the factorial of 3:

    dotnet run -- 3

  5. The command produces this output: The factorial of 3 is 6.

Note

When running an application in Visual Studio, you can specify command-line arguments in the Debug Page, Project Designer.

3. Top-level statements

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021-2024 Mingwei Li
  • Visitors: | Views:

Buy me a bottle of beer please~

支付宝
微信