前言

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

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

作者认为新人应该先打好基础,不要直接学习框架,例如先掌握 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

Asp.net core 少走弯路系列教程(六)C# 语法学习的更多相关文章

  1. 学习ASP.NET Core Razor 编程系列十六——排序

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  2. 学习ASP.NET Core Blazor编程系列十六——排序

    学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...

  3. 学习ASP.NET Core Blazor编程系列二十六——登录(5)

    学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...

  4. 学习ASP.NET Core Razor 编程系列六——数据库初始化

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  5. 学习ASP.NET Core Blazor编程系列六——初始化数据

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  6. 学习ASP.NET Core Razor 编程系列九——增加查询功能

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  7. 学习ASP.NET Core Razor 编程系列十九——分页

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  8. 学习ASP.NET Core Razor 编程系列十七——分组

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  9. 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  10. 学习ASP.NET Core Razor 编程系列七——修改列表页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

随机推荐

  1. 载誉而归!天翼云荣获第23届中国IT用户满意度大会多项殊荣

    10月25日,2024第23届中国IT用户满意度大会暨首届工业产品满意度交流会在北京举行.现场揭晓"2024中国IT用户满意度征集结果",天翼云凭借领先的产品技术.完善的客户服务以 ...

  2. 如何在WPS和Word/Excel中直接使用DeepSeek功能

    以下是将DeepSeek功能集成到WPS中的详细步骤,无需本地部署模型,直接通过官网连接使用:1. 下载并安装OfficeAI插件 (1)访问OfficeAI插件下载地址:https://www.of ...

  3. LeetCode 第1题:两数之和

    LeetCode 第1题:两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标. 你可以 ...

  4. 【忍者算法】从照片旋转到矩阵变换:探索图像旋转问题|LeetCode 48 旋转图像

    从照片旋转到矩阵变换:探索图像旋转问题 生活中的旋转 在这个自拍时代,我们经常需要调整照片的方向.有时拍出来的照片歪了,需要旋转90度:有时想要换个角度看看效果,来回旋转照片.这种旋转操作不仅存在于我 ...

  5. 在flink消费一段时间kafka后,kafka-group的offset被重置了是怎么回事?

    一.背景 腾讯Flink使用 KafkaSource API创建source端,源码中默认开启了checkpoint的时候提交offset 到kafka-broker.读取kafka数据写入到iceb ...

  6. Atcoder ABC383E Sum of Max Matching 题解 [ 绿 ] [ 最小瓶颈路 ] [ 并查集 ] [ Kruskal 重构树 ]

    Sum of Max Matching:简单贪心,但我场上没切,唐完了. 思路 显然,对于最大边权最小问题,首先想到最小瓶颈路的 trick:按边的大小排序,对原图进行加边. 同时可以发现,这个匹配有 ...

  7. 一分钟搞定!CentOS 7.9上用Ansible自动化部署SQL Server 2019

    一分钟搞定!CentOS 7.9上用Ansible自动化部署SQL Server 2019 不熟悉整个流程的朋友可以先看之前的部署文章,手动部署一遍 一步步教你在CentOS 7.9上安装SQL Se ...

  8. day:2 软件测试流程——H模型

    软件测试流程_H 模型 一.详细流程 1.产品召开需求澄清会议,产品.开发.测试都参加 2.测试和开发拿到需求 3.测试经理拿到需求,根据需求编写测试计划 测试计划(内容:测试目的,背景,范围,测试准 ...

  9. 莫托曼机器人GP110B操作手柄故障维修全攻略

     莫托曼机器人GP110B操作手柄故障机器人维修全攻略              一.前言              莫托曼机器人GP110B操作手柄是机器人控制系统的重要组成部分,它允许操作人员对机 ...

  10. OSAL架构

    OSAL操作系统最多可以支持16个任务,由任务功耗管理PwrMgr_task_state变量可知,而OSAL每个任务最多只能支持16个事件处理,理论上最大可以执行256个事件处理. 对于一些运算能力不 ...