Loading

Asp.net core 少走弯路系列教程(六)C# 语法学习

前言

新人学习成本很高,网络上太多的名词和框架,全部学习会浪费大量的时间和精力。

新手缺乏学习内容的辨别能力,本系列文章为新手过滤掉不适合的学习内容(比如多线程等等),让新手少走弯路直通罗马。

作者认为新人应该先打好基础,不要直接学习框架,例如先掌握 SQL 再使用 EFCore 框架。

作者只传授数年内不会变化的知识,让新手学习快速进入跑道受益终身。

分享使我快乐,请务必转发给同学,朋友,让大家都少走一些弯路!!


Hello world

安装 dotnet SDK:https://dotnet.microsoft.com/zh-cn/download

安装 Visual Studio:https://visualstudio.microsoft.com/downloads

习惯使用命令行创建项目:


dotnet new console

“Hello, World”程序历来都用于介绍编程语言。 下面展示了此程序的 C# 代码:

using System;

class Hello
{
    static void Main()
    {
        Console.WriteLine("Hello, World");
    }
}

以下大纲概述了 C# 的类型系统。

  • 值类型
    • 简单类型
      • 有符号整型:sbyte、short、int、long
      • 无符号整型:byte、ushort、uint、ulong
      • Unicode 字符:char,表示 UTF-16 代码单元
      • IEEE 二进制浮点:float、double
      • 高精度十进制浮点数:decimal
      • 布尔值:bool,表示布尔值(true 或 false)
    • 枚举类型
      • enum E {...} 格式的用户定义类型。 enum 类型是一种包含已命名常量的独特类型。 每个 enum 类型都有一个基础类型(必须是八种整型类型之一)。 enum 类型的值集与基础类型的值集相同。
    • 结构类型
      • 格式为 struct S {...} 的用户定义类型
    • 可以为 null 的值类型
      • 值为 null 的其他所有值类型的扩展
    • 元组值类型
      • 格式为 (T1, T2, ...) 的用户定义类型
  • 引用类型
      • 其他所有类型的最终基类:object
      • Unicode 字符串:string,表示 UTF-16 代码单元序列
      • 格式为 class C {...} 的用户定义类型
    • 接口
      • 格式为 interface I {...} 的用户定义类型
    • 数组类型
      • 一维、多维和交错。 例如:int[]、int[,] 和 int[][]
    • 委托类型
      • 格式为 delegate int D(...) 的用户定义类型

C# 条件语句、循环语句、方法定义与 JavaScript 语法基本一致,本文不重复讲述。


public class Point
{
    public int X { get; }
    public int Y { get; }
    
    public Point(int x, int y) => (X, Y) = (x, y);
}

var p1 = new Point(0, 0);
var p2 = new Point(10, 20);

class 的成员要么是静态成员,要么是实例成员。 静态成员属于类,而实例成员则属于对象(类实例)。

  • 常量:与类相关联的常量值
  • 字段:与类关联的变量
  • 方法:类可执行的操作
  • 属性:与读取和写入类的已命名属性相关联的操作
  • 构造函数:初始化类实例或类本身所需的操作

class 的成员都有关联的可访问性,用于控制能够访问成员的程序文本区域。以下内容对访问修饰符进行了汇总。

  • public:访问不受限制。
  • private:访问仅限于此类。
  • protected:访问仅限于此类或派生自此类的类。
  • internal:仅可访问当前程序集(.exe 或 .dll)。

理解类字段和 static,在以下示例中,每个 Color 类实例均包含 R、G 和 B 实例字段的单独副本,但只包含 Black、White、Red、Green 和 Blue 静态字段的一个副本:

public class Color
{
    public static readonly Color Black = new(0, 0, 0);
    public static readonly Color White = new(255, 255, 255);
    public static readonly Color Red = new(255, 0, 0);
    public static readonly Color Green = new(0, 255, 0);
    public static readonly Color Blue = new(0, 0, 255);
    
    public byte R;
    public byte G;
    public byte B;

    public Color(byte r, byte g, byte b)
    {
        R = r;
        G = g;
        B = b;
    }
}

var c1 = Color.Black; //static
var c2 = new Color(255, 0, 0);

理解类属性和 static,与字段行为一致,但是定义有区别

    public byte R { get; set; }
    public byte G { get; } //不加 set 相当于只读属性
    public byte B { get; set; } = 100; //初始化

理解类方法和 static

class Color
{
    public static string StaticString() => "This is an static method";
    public override string ToString() => "This is an object";
}

string str1 = Color.StaticString(); //static
string str2 = new Color().ToString();

方法重载

class OverloadingExample
{
    static void F() => Console.WriteLine("F()");
    static void F(object x) => Console.WriteLine("F(object)");
    static void F(int x) => Console.WriteLine("F(int)");
    static void F(double x) => Console.WriteLine("F(double)");
    static void F<T>(T x) => Console.WriteLine($"F<T>(T), T is {typeof(T)}");            
    static void F(double x, double y) => Console.WriteLine("F(double, double)");
    
    public static void UsageExample()
    {
        F();            // Invokes F()
        F(1);           // Invokes F(int)
        F(1.0);         // Invokes F(double)
        F("abc");       // Invokes F<T>(T), T is System.String
        F((double)1);   // Invokes F(double)
        F((object)1);   // Invokes F(object)
        F<int>(1);      // Invokes F<T>(T), T is System.Int32
        F(1, 1);        // Invokes F(double, double)
    }
}

理解方法参数 out/ref

static void Swap(ref int x, ref int y)
{
    int temp = x;
    x = y;
    y = temp;
}
public static void SwapExample()
{
    int i = 1, j = 2;
    Swap(ref i, ref j);
    Console.WriteLine($"{i} {j}");    // "2 1"
}

static void Divide(int x, int y, out int result, out int remainder)
{
    result = x / y;
    remainder = x % y;
}
public static void OutUsage()
{
    Divide(10, 3, out int res, out int rem);
    Console.WriteLine($"{res} {rem}");	// "3 1"
}

泛型类

public class Pair<TFirst, TSecond>
{
    public TFirst First { get; }
    public TSecond Second { get; }
    
    public Pair(TFirst first, TSecond second) => 
        (First, Second) = (first, second);
}

var pair = new Pair<int, string>(1, "two");
int i = pair.First;     //TFirst int
string s = pair.Second; //TSecond string

继承类

public class Point3D : Point
{
    public int Z { get; set; }
    
    public Point3D(int x, int y, int z) : base(x, y)
    {
        Z = z;
    }
}

Point a = new(10, 20);
Point b = new Point3D(10, 20, 30);

虚类

public abstract class Expression
{
    public abstract double Evaluate(Dictionary<string, object> vars);
}

public class Constant : Expression
{
    double _value;
    
    public Constant(double value)
    {
        _value = value;
    }
    
    public override double Evaluate(Dictionary<string, object> vars)
    {
        return _value;
    }
}

接口

interface IControl
{
    void Paint();
}
interface IDataBound
{
    void Bind(Binder b);
}

public class EditBox : IControl, IDataBound
{
    public void Paint() { }
    public void Bind(Binder b) { }
}

EditBox editBox = new();
IControl control = editBox;
IDataBound dataBound = editBox;

枚举

public enum SomeRootVegetable
{
    HorseRadish,
    Radish,
    Turnip
}

可为 null 的类型

int? optionalInt = default; 
optionalInt = 5;
string? optionalText = default;
optionalText = "Hello World.";

匿名类型

var v = new { Amount = 108, Message = "Hello" };
Console.WriteLine(v.Amount + v.Message);

数组

int[] a = new int[10];
for (int i = 0; i < a.Length; i++)
{
    a[i] = i * i;
}
for (int i = 0; i < a.Length; i++)
{
    Console.WriteLine($"a[{i}] = {a[i]}");
}

//语法糖
int[] a1 = new int[] { 1, 2, 3 };
int[] a2 = { 1, 2, 3 };

foreach (int item in a2)
{
    Console.WriteLine(item);
}

列表

var names = new List<string> { "<name>", "Ana", "Felipe" };
foreach (var name in names)
{
  Console.WriteLine($"Hello {name.ToUpper()}!");
}
foreach (var a = 0; a < names.Count; a++)
{
  Console.WriteLine($"Hello {names[a].ToUpper()}!");
}

names.Add("Maria"); //添加
names.Add("Bill");
names.Remove("Ana"); //移除
foreach (var name in names)
{
  Console.WriteLine($"Hello {name.ToUpper()}!");
}

names.Sort(); //排序

异常

try
{
    var a = 1 / 0;
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}
finally
{
    Console.WriteLine("无论是不是报错,这里都会打印");
}

LINQ

List<int> numbers = new() { 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };

IEnumerable<int> queryFactorsOfFour = numbers.Where(num => num % 4 == 0);

List<int> factorsofFourList = queryFactorsOfFour.ToList(); //新实例
Console.WriteLine(factorsofFourList[2]);
factorsofFourList[2] = 0;
Console.WriteLine(factorsofFourList[2]);

C# 语言太复杂了,其实很多特性都用不上,这里给几个提示:

  • 不要使用 dynamic 类型
  • 尽量使用 lambda linq 链式语法
  • 尽量花时间了解 using System.Collections.Generic 下面的数据结构,列表/队列/栈/字典
  • 本文以外的知识点,以后再慢慢补充学习

C# 语言还有很多知识内容,但是对新手而已学到这里算入门了,千万不要指望一下能吃下所有内容(贪吃蛇的后果),只有反复的实战才能彻底领会贯通。

到这里,你已经对 C# 语言有了初步的认识,为我们以后深入打下了基础,下一篇我们学习 Asp.net core WebApi 知识吧!


系列文章导航

原创保护,转载请注明出处:https://www.cnblogs.com/FreeSql/p/16782488.html

posted @ 2022-10-11 20:29  FreeSql  阅读(1421)  评论(1编辑  收藏  举报