.NET-2.C#基础+进阶


前言

入门知识记录。

内容参考:
官方中文文档C#更细节的Enumerable 类菜鸟教程C#C语言中文网非常好的教程十分齐全意外的发现


一、基本语法

C# 是一个简单的、现代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的。

//1.第一个helloworld
using System; //引入命名空间
namespace HelloWorldApplication//命名空间
{
    class HelloWorld
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

//2. 注释 
1.单行注释
2.多行注释     /*多行 注释*/
3.XML注释(有输入智能提示的)(///即可vs里面自动添加)
下列为常用的,其余可[参考](https://www.runoob.com/note/22384)

//3. 访问修饰符:
public:所有对象都可以访问;
private:对象本身在对象内部可以访问;
protected:只有该类对象及其子类对象可以访问
internal:同一个程序集的对象可以访问;
protected internal:访问限于当前程序集或派生自包含类的类型

//4. 数据类型
指针类型(Pointer types)
值类型:bool、byte、char、decimal、double、float、int、long、struct 、 enum 
引用类型:object、dynamic 和 string。

//5. 类型转换方法:
ToBoolean  ToByte  	ToChar  ToDateTime ToDecimal  ToDouble ToInt32  ToString ToUInt32
-  使用sizeof(type)方法判断类型
- **当一个值类型转换为对象类型时,则被称为 装箱;另一方面,当一个对象类型转换为值类型时,则被称为 拆箱。**
- 单问号 ? 与 双问号 ??
- 类型转换,隐式类型转换 和显示类型转换
- typeof()	返回 class 的类型。
- as	强制转换

//6. 变量、常量、运算符、判断、循环
/算术运算符+ - * / % ++ --
关系运算符==  !=  >  <   >=   <=
逻辑运算符&& (and)||(or) !
位运算符&、 | 和 ^  ~ <<   >>
赋值运算符= += -= *= /=
其他运算符sizeof() typeof() & *  ? :  is  as
//if...else 语句   switch 语句
>while 循环   for/foreach 循环  do...while 循环
```c
int i;//变量声明
i=100;//赋值
int d = 3, f = 5;  
const int a = 5;
c = a++;// 先将 a 赋值给 c,再对 a 进行自增运算。
c = ++a;//先将 a 进行自增运算,再将 a 赋值给 c 。
c = a--;//先将 a 赋值给 c,再对 a 进行自减运算。
c = --a;//先将 a 进行自减运算,再将 a 赋值给 c 。

//无限循环
for (; ; )
Console.WriteLine("Hey! I am Trapped");
//循环swich
int day = 4;
switch (day)
{
  case 1:
    Console.WriteLine("Monday");
    break;
  case 7:
    Console.WriteLine("Sunday");
    break;
}  
//-----------------------
int []  n = new int[10]; /* n 是一个带有 10 个整数的数组 */
/* 初始化数组 n 中的元素 */        
for ( int i = 0; i < 10; i++ )
  n[i] = i + 100;

/* 输出每个数组元素的值 */
foreach (int j in n )
{
  int i = j-100;
  Console.WriteLine("Element[{0}] = {1}", i, j);
}

数组(Array)、函数

//数组
datatype[] arrayName;//声明一个数组
double[] balance;
double[] balance = new double[10];//初始化数组
balance[0] = 4500.0;
//double[] balance = { 2340.0, 4523.69, 3421.0};
//int [] marks = new int[5]  { 99,  98, 92, 97, 95};
//int [] marks = new int[]  { 99,  98, 92, 97, 95};
//List的简单用法
List<student> stringlist =new List<student>() {new student(1, "zhouy11", 12),new student(2, "zhouy22", 22)};
student[] arrstr = { new student(4,"zhouyi444",44),new student(5,"zhouyi55",55)};
stringlist.Add(new student(3,"zhouyi33",33));
stringlist.AddRange(arrstr);
foreach (var item in stringlist)
{
    Console.WriteLine(item);
}
Console.WriteLine(stringlist.Capacity.ToString()+stringlist.Count.ToString());
public record student(int id, string name, int age);

//函数
//params 关键字
void getid(params int[] aa)
{
    foreach (var item in aa)
    {
        Console.WriteLine(item);
    }
}
getid(1,2,3);
//out 参数用法
void getTest(out int a, out int b)
{
    a = Convert.ToInt32(Console.ReadLine());
    b = Convert.ToInt32(Console.ReadLine());
}

int a, b;
getTest(out a,out b);
Console.WriteLine($"{a}+{b}");

Dictionary、Enum、Struct

一些基本 操作

//Dictionary
//1,不能有相同的key
Dictionary<int, int> dic = new Dictionary<int, int>();
dic.Add(1, 1);dic.Add(2, 2);dic.Add(3, 3);
int i, j;
Console.WriteLine(dic.Count);
Console.WriteLine(dic.Keys); //获取key的集合
Console.WriteLine(dic.Values);//获取value的值
Console.WriteLine(dic.GetType());
Console.WriteLine(dic.TryGetValue(1, out i));
Console.WriteLine(dic.TryGetNonEnumeratedCount(out j));
Console.WriteLine(dic.TryAdd(4, 4));
Console.WriteLine(dic.ContainsKey(1));
Console.WriteLine(dic.ContainsValue(1));
Console.WriteLine(i);
Console.WriteLine(j);
dic.Remove(1);//从 Dictionary中移除所指定的键的值。
dic.Clear();//移除所有


//Enum
enum 是值类型枚举类型
是用来规范同一范围的一些数据,(水果,职业,等等)
Console.WriteLine((int)occupation.dentist);
Console.WriteLine((int)occupation.doctor);
Console.WriteLine(occupation.dentist);
enum occupation
{
    doctor=2,
    dentist=2,
    teacher,
    student
}

//Struct
person p;
p.name = "zhou";
Console.WriteLine(p.name);
struct person
{
    public int id;
    public string name;
}

二、C# 新语法(C#8.0、C#9.0和C#10.0)

1.顶级语句
2.全局using 指令
3.Using资源管理
4.文件范围的命名空间声明
5.可空的引用类型
6.记录(record)类型(C#9)

//1.顶级语句(C#9.0)有点像python那种感觉
1、直接在C#文件中直接编写入口方法的代码,不用类,不用Main。经典写法仍然支持。反编译一下了解真相。
2、同一个项目中只能有一个文件具有顶级语句。
3、顶级语句中可以直接使用await语法,也可以声明函数


//2.全局using 指令(C#10)
1、将 global 修饰符添加到 using 前,这个命名空间就应用到整个项目,不用重复using。
2、通常创建一个专门用来编写全局using代码的C#文件。
3、如果csproj中启用了<ImplicitUsings>enable</ImplicitUsings>,编译器会自动隐式增加对于System、System.Linq等常用命名空间的引入,不同各类型项目引入的命名空间也不一样。


//3.Using资源管理的问题
1.实现了IDisposible接口的对象可以用using进行管理。
2.如果一段代码中有很多非托管资源需要被释放的话,代码中就会存在着多个嵌套的using语句。
3.在实现了Idisposable/IAsyncDisposable接口的类型的变量声明前加上using,当代码执行离开变量的作用域时,对象就会被释放。

using var outStream = File.OpenWrite("e:/1.txt");
using var writer = new StreamWriter(outStream);
writer.WriteLine("hello");
string s = File.ReadAllText("e:/1.txt");
Console.WriteLine(s);


//4.文件范围的命名空间声明(C#10)
namespace TMS.Admin;//这里哦
class Teacher
{
    public int Id { get; set;  }
    public string Name {  get; set; }
}

//5.可空的引用类型(C#8)
1、C#数据类型分为值类型和引用类型两种,值类型的变量不可以为空,而引用类型变量可以为空。
2、问题:如果不注意检查引用类型变量是否可空,就有可能造成程序中出现NullReferenceException异常。
3、csproj中<Nullable>enable</Nullable>启用可空引用类型检查。
4、在引用类型后添加“?”修饰符来声明这个类型是可空的。对于没有添加“?”修饰符的引用类型的变量,如果编译器发现存在为这个变量赋值null的可能性的时候,编译器会给出警告信息
5、如果程序员确认被访问的变量、成员确实不会出现为空的情况,也可以在访问可空的变量、成员的时候加上!来抑制编译器的警告。
public class Student
{
	public string Name {  get; set; }
	public string? PhoneNumber { get; set; }
	public Student(string name)
	{
		this.Name = name;
	}
}


//6.记录(record)类型(C#9)
1、C#中的==运算符默认是判断两个变量指向的是否是同一个对象,即使两个对象内容完全一样,也不相等。可以通过重写Equals方法、重写==运算符等来解决这个问题,不过需要开发人员编写非常多的额外代码。
2、在C#9.0中增加了记录(record)类型的语法,编译器会为我们自动生成Equals、GetHashcode等方法。

public record Person(string FirstName, string LastName);
Person p1 = new Person("aaa", "bbb");
Person p2 = new Person("aaa","bbb");
Person p3 = new Person("ccc", "ddd");
Console.WriteLine(p1);
Console.WriteLine(p1==p2);
Console.WriteLine(p1==p3);
Console.WriteLine(p1.FirstName);

1、可以实现部分属性是只读的、而部分属性是可以读写。
2、默认生成的构造方法的行为不能修改,我们可以为类型提供多个构造方法,然后其他构造方法通过this调用默认的构造方法。
3、也推荐使用只读属性的类型。这样的所有属性都为只读的类型叫做“不可变类型”,可以让程序逻辑简单,减少并发访问、状态管理等的麻烦。

//对象的副本
1、record也是普通类,变量的赋值是引用的传递。这是和结构体不同之处。
2、生成一个对象的副本,这个对象的其他属性值与原对象的相同,只有一个或者少数几个属性改变。麻烦的做法:User u2 = new User(u1.UserName, "test@example", u1.Age);
3、用with关键字简化:User u2 = u1 with { Email= “test@example” }; 创建的也是拷贝。

三、功能模块

1.json获取指定key的value

// 测试:
string strJson = @"{'1':{'id':{'ip':'192.168.0.1','p':34,'pass':'ff','port':80,'user':'t'}},'code':0}";
string key = "port";
string aa=GetJsonValue(strJson, key);
Console.WriteLine(aa);
string GetJsonValue(string strJson, string key)
{
    string strResult = "";
    JObject jsonObj = JObject.Parse(strJson);
    strResult = GetNestJsonValue(jsonObj.Children(), key);
    return strResult;
}

string GetNestJsonValue(JEnumerable<JToken> jToken, string key)
{
    IEnumerator enumerator = jToken.GetEnumerator();
    while (enumerator.MoveNext())
    {
        JToken jc = (JToken) enumerator.Current;
        if (jc is JObject || ((JProperty) jc).Value is JObject)
        {
            return GetNestJsonValue(jc.Children(), key);
        }
        else
        {
            if (((JProperty) jc).Name == key)
            {
                return ((JProperty) jc).Value.ToString();
            }
        }
    }

    return null;

2.文件系统

参考

Console.WriteLine(Directory.GetCurrentDirectory());//获取当前的路径
Console.WriteLine(Path.Combine("runtimes","win"));//获取联结路径runtimes/win
IEnumerable<string> listOfDirectories = Directory.EnumerateDirectories(@"D:\C#project\Xamarin\ConsoleApp1\ConsoleApp1");//列出所有目录
IEnumerable<string> listOfFiles  = Directory.EnumerateFiles(@"D:\C#project\Xamarin\ConsoleApp1\ConsoleApp1");//列出所有文件
IEnumerable<string> allfilesanddir  = Directory.EnumerateFiles(@"D:\C#project\Xamarin\ConsoleApp1\ConsoleApp1","*.txt",SearchOption.AllDirectories);//所有的.txt
foreach (var item in listOfDirectories)
{
    Console.WriteLine($"{item}");
}
foreach (var item in listOfFiles)
{
    Console.WriteLine($"{item}");
}
Console.WriteLine("sadfasdfsad");
foreach (var item in allfilesanddir)
{
    Console.WriteLine($"{item}");
}

//-------
//如果“/demo”尚不存在,将自动创建该文件夹
Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), "demo"));
//确保目录存在
bool existdir = Directory.Exists(Path.Combine(Directory.GetCurrentDirectory(), "demo"));
Console.WriteLine($"{existdir}");
// 创建文件 创建一个名为 greeting.txt 的文件,其中包含文本“Hello World!”
File.WriteAllText(Path.Combine(Directory.GetCurrentDirectory(), "greeting.txt"), "Hello World!");
Console.Write(string.Empty);//string.Empty代表空。
//从文件读取数据
var text = File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(), "greeting.txt"));
Console.WriteLine($"{text}");
// 将数据追加到文件
File.AppendAllText(Path.Combine(Directory.GetCurrentDirectory(),"greeting.txt"),"这是追加的内容");
var text = File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(), "greeting.txt"));
Console.WriteLine($"{text}");

//--------------------------------
using System.Diagnostics;
using Newtonsoft.Json;
//json数据获取
var salesJson = File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(),"demo.json"));
Console.WriteLine($"{salesJson}");
var salesData = JsonConvert.DeserializeObject<SalesTotal>(salesJson);
Console.WriteLine(salesData.Total);
class SalesTotal
{
    public double Total { get; set; }
}

3.字符串的操作

1.字符串的分割
// string phrase = "The fox jumps  over";
// string[] words = phrase.Split(' ');
//--------------
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string text = "one\ttwo three:four,five six seven";
System.Console.WriteLine($"Original text: '{text}'");
string[] words1 = text.Split(delimiterChars);
foreach (var word in words1)
{
    System.Console.WriteLine($"<{word}>");
}
2.连接字符串
using System.Text;
string date=DateTime.Today.ToShortDateString();//日期
Console.WriteLine($"{date}");
string[] words = {"aaa", "bbb","ccc"};
var cat = string.Concat(words);//联接集合中的字符串
var dog = string.Join("11", words);//联接集合中的字符串
//该选项可能会导致更多的分配
var phrase = words.Aggregate((partialPhrase, word) =>$"{partialPhrase}11{word}");
Console.WriteLine($"{cat+dog+phrase}");
3.搜索字符串
//字符串包含文本
string factMessage = "aaabbbcccddd";
Console.WriteLine($"\"{factMessage}\"");
bool consreach = factMessage.Contains("aa");
bool startwords = factMessage.StartsWith("aa");
bool endwords = factMessage.EndsWith("dd");
Console.WriteLine($"{consreach+startwords.ToString() +endwords}");
//字符串的什么位置
int first = factMessage.IndexOf("a");
int second = factMessage.LastIndexOf("a");
int third = factMessage.IndexOfAny(new []{'b','d'});
int four = factMessage.LastIndexOfAny(new []{'b','d'});
Console.WriteLine($"{first.ToString()+second.ToString()+third.ToString()+four.ToString()}");
//正则搜索?????
4. 修改的字符串
string source = "  aaa bbb ccc    ";
var replacement = source.Replace("aaa", "111");
var replacement1 = source.Replace(' ', '_');
Console.WriteLine($"{source+replacement+replacement1}");
//去除空格
var trimmedResult = source.Trim();//前后空格
var trimLeading = source.TrimStart();
var trimTrailing = source.TrimEnd();
Console.WriteLine($"<{source+trimmedResult+trimLeading+trimTrailing}>");
var text = source.Remove(0, 4);//删除文本
Console.WriteLine($"{text}");

4.维码

//添加NuGet SkiaSharp.QrCode 包
using SkiaSharp;
using SkiaSharp.QrCode;

var content = "这里是扫描后的结果";
//创建生成器
using (var generator = new QRCodeGenerator())
{
    // 设置错误校正能力(ECC)级别
    //L:最大纠错率7%M:最大纠错率15%Q:最大纠错率25%H:最大纠错率30%
    //是否还能识别
    var qr = generator.CreateQrCode(content, ECCLevel.H);
 
    // 创建一个Canvas
    var info = new SKImageInfo(512, 512);
    using (var surface = SKSurface.Create(info))
    {
        var canvas = surface.Canvas;
 
        // 渲染二维码到Canvas
        canvas.Render(qr, info.Width, info.Height);
 
        // 输出到文件
        using (var image = surface.Snapshot())
        using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
        using (var stream = File.OpenWrite(@"QRCode.png"))
        {
            data.SaveTo(stream);
            Console.WriteLine("true");
        }
    }
}

5.邮箱验证、语音播报

//值得参考
var rgb = (255, 100, 30);
// Initialization & assignment
int r;
(r, int g, int b) = rgb;
Console.WriteLine($"RGB: {r}, {g}, {b}");
// Output: RGB: 255, 100, 30

//邮箱验证。
static bool IsEmailAddress(string email)
{
    if (string.IsNullOrWhiteSpace(email))
        return false;
 
    var symbolIndex = email.IndexOf('@');
    return symbolIndex > 0
           && symbolIndex < email.Length - 1
           && symbolIndex == email.LastIndexOf('@');
}
//有且仅有一个@并且前后都有字符
var text=IsEmailAddress("afd@saf");
Console.WriteLine($"{text}");


//语音播报
using System.Speech.Synthesis;
SpeechSynthesizer speech = new SpeechSynthesizer();
Console.Write("请输入文字:");
string str = Console.ReadLine();
speech.Volume = 10;
speech.Speak(str);

6.序列化对象

参考Newtonsoft.Json介绍

using System.ComponentModel;
using Newtonsoft.Json;
Person product = new Person
{
    Name = "zhou",
    Price = 1,
    Hobby = new [] { "aa", "bb", "cc" }
};
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.DateFormatString = "yyyy-MM-dd";//设置日期格式
settings.Formatting = Formatting.Indented;//实现缩进
settings.NullValueHandling = NullValueHandling.Ignore;//忽略空值
settings.DefaultValueHandling = DefaultValueHandling.Ignore;//[DefaultValue("zhou1")]当值为zhou1忽略


var json = JsonConvert.SerializeObject(product,settings);//序列化对象
Console.WriteLine(json);
Person deserializedProduct = JsonConvert.DeserializeObject<Person>(json);//反序列化对象
Console.Write(deserializedProduct);
public class Person
{
   
    public String[] Hobby { get; set; }
    public int  Price { get; set; }
    [DefaultValue("zhou1")]
    [JsonProperty(propertyName:"Cname",NullValueHandling = NullValueHandling.Ignore)]//自定义序列化字段名,空值忽略
    public string Name { get; set; }
    [JsonProperty]//支持非公共成员
    private int Height { get; set; }
}



//======
//Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity的。
//序列化DataTable

using System.Data;
using Newtonsoft.Json;

DataTable dt = new DataTable();
dt.Columns.Add("Age", Type.GetType("System.Int32"));
dt.Columns.Add("Name", Type.GetType("System.String"));
dt.Columns.Add("Sex", Type.GetType("System.String"));
dt.Columns.Add("IsMarry", Type.GetType("System.Boolean"));
for (int i = 0; i < 4; i++)
{
    DataRow dr = dt.NewRow();
    dr["Age"] = i + 1;
    dr["Name"] = "Name" + i;
    dr["Sex"] = i % 2 == 0 ? "男" : "女";
    dr["IsMarry"] = i % 2 > 0 ? true : false;
    dt.Rows.Add(dr);
}

var json = JsonConvert.SerializeObject(dt, Formatting.Indented);
//Console.WriteLine(json);
 var text = JsonConvert.DeserializeObject<DataTable>(json);
foreach (DataRow item in text.Rows)
{
    Console.WriteLine($"{item[0].ToString()+item[1]}");
}
//默认情况下,所有的成员不会被序列化OptIn,[JsonProperty]使属性会被序列化
[JsonObject(MemberSerialization.OptIn)]
public class person
{
    public int id { get; set; }
    [JsonProperty]
    public string name { get; set; }
    public string sex { get; set; }
}
//默认情况下,所有的成员会被序列化OptOut,[JsonIgnore]使属性不会被序列化
[JsonObject(MemberSerialization.OptOut)]
public class person1
{
    public int id { get; set; }
    [JsonIgnore]
    public string name { get; set; }
    public string sex { get; set; }
}

7.小小爬虫

https://html-agility-pack.net/documentation
https://www.cnblogs.com/cdaniu/p/15579438.html
https://blog.csdn.net/joyyi9/article/details/120528050
https://www.cnblogs.com/lavender000/category/1013349.html
https://cloud.tencent.com/developer/article/1876712
https://www.cnblogs.com/netcore5/p/15415350.html

就直接上码了!

# Html Parser
1. From File	
SaveHtmlFile();		
#region example  
var path = @"test.html";
var doc = new HtmlDocument();
doc.Load(path);

var node = doc.DocumentNode.SelectSingleNode("//body");
Console.WriteLine(node.OuterHtml);
#endregion
private static void SaveHtmlFile()
{
   var html =
      @"<!DOCTYPE html>
<html>
<body>
<h1>This is <b>bold</b> heading</h1>
<p>This is <u>underlined</u> paragraph</p>
<h2>This is <i>italic</i> heading</h2>
</body>
</html> ";

      var htmlDoc = new HtmlDocument();
      htmlDoc.LoadHtml(html);
   
   htmlDoc.Save("test.html");
}

2. From String	
 var html =
      @"<!DOCTYPE html>
<html>
<body>
<h1>This is <b>bold</b> heading</h1>
<p>This is <u>underlined</u> paragraph</p>
<h2>This is <i>italic</i> heading</h2>
</body>
</html> ";

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body");
Console.WriteLine(htmlBody.OuterHtml);
3. From Web
Console.WriteLine("zhouyi");
var html = @"https://dotnet9.com/";
HtmlWeb web = new HtmlWeb();
var htmlDoc = web.Load(html);
var allNodes = htmlDoc.DocumentNode.SelectNodes("/html/body/article/div[2]/div/ul/li/a/text()");
foreach (var item in allNodes)
{
   Console.WriteLine(item.InnerText);
}

4. From Browser



# HTML Selectors
>SelectNodes()	
>SelectSingleNode(String)
string name = htmlDoc.DocumentNode
    .SelectNodes("//td/input")
    .First()
    .Attributes["value"].Value;
string name = htmlDoc.DocumentNode
    .SelectSingleNode("//td/input")
    .Attributes["value"].Value;


# Manipulation
properties:
1. InnerHtml
2. InnerText
3. OuterHtml
4. ParentNode
methods:
https://html-agility-pack.net/manipulation

# Traversing
https://html-agility-pack.net/traversing

# 小栗子
var title = item.Attributes.Where(x => x.Name == "title").FirstOrDefault().Value;

四、C# 进步本

1. 字符数组声明、赋值,字符串转换为字符数组
char[] a=new []{'1','a'};
string b="qrewt";
char[] c=b.ToCharArray();

2. 插值语法(两种方式)
string a = "aaa", b = "bbb",c="cccc";
Console.WriteLine("第一个值:{0},第二个值:{1},第三个值{2}",a,b,c);
Console.WriteLine($"第一个值:{a},第二个值:{b},第三个值{c}");
string userID = "1";string sql = @" UserID = '{0}'";sql=string.Format(sql, userID);

3. Console 类中常用方法
Console.WriteLine("换行");
Console.Write("不换行");
int a =Console.Read();
string b =Console.ReadLine();

4. Math 类中常用方法
Console.WriteLine(Math.Max(1, 23));
int[] nums=new int[]{2,3,4};nums.Max();
Console.WriteLine(Math.Min(1, 23));
Console.WriteLine(Math.Pow(2, 3));//2*2*2
Console.WriteLine(Math.Sqrt(4)); //数字的平方根
Console.WriteLine(Math.Round(2.33, 1));//保留一位小数点
int c ; Console.WriteLine(Math.DivRem(5, 4, out c));//余数

5. Random类中常用方法
Random random = new Random();
Console.WriteLine(random.Next());//产生一个不同的随机正整数
Console.WriteLine(random.Next(1,10));//范围内
Console.WriteLine(random.NextDouble().ToString("0.00"));//0.0~1.0
Console.WriteLine(random.NextSingle());//0.0~1.0
var a = new byte[5];
random.NextBytes(a);
foreach (var i in a)
{
    Console.WriteLine(i);
}

6. 类型转换、以及书写任意类型的转换
double a=1.1; 
int b=(int)a;
int b1 = Convert.ToInt32(a);
int b2 = (int)Convert.ChangeType(a,typeof(Int32));
int b3=Int32.Parse("12");//将字符串转换为int
Console.WriteLine($"{b}={b1}={b2}={b3}");
//任意类型的转换
static T GetValue<T>(object obj)
{
    return (T)Convert.ChangeType(obj, typeof(T));
}
Console.WriteLine(GetValue<int>(a));

7. Guid的创建与转换(全局唯一标识符GUID,Globally Unique Identifier)
Guid u= Guid.NewGuid();
var uuid = u.ToString(); //转换为字符串
Guid aGuid = Guid.Parse(uuid);//字符串转换为Guid
Console.WriteLine(uuid+aGuid);

8. HttpClient 最简单的使用
using (HttpClient httpClient = new HttpClient())
{
    var html = await httpClient.GetStringAsync("https://www.baidu.com/");
    Console.WriteLine(html);
}

9. yield 简单使用
foreach(var s in  Test())
{
    Console.WriteLine(s);
}
static  IEnumerable<string> Test()
{
    yield return "aaa";
    yield return "bbb";
    yield return "ccc";
}

10. TryParse()方法
double result;
bool aa=Double.TryParse("11",out result);
Console.WriteLine($"{result}+++{aa}");

11. 冒泡排序
int[] arr=new []{2,1,3,4,5};
for (var i = 0; i < arr.Length; i++)
{
    for (int j = 0; j < arr.Length-i-1; j++)
    {
        if (arr[j]<arr[j+1])
        {
            int temp;
            temp = arr[j+1];
            arr[j+1] = arr[j];
            arr[j] = temp;
        }
    }
}
foreach (var i in arr)
    Console.WriteLine(i);


12. var 关键字
1.必须在定义时初始化。var a;a=1;//报错
2.初始化完成后,不能赋值其他类型var b=1;b="aa";//报错

13. 字符串去除重复
string StringEliminateDuplicate(string str)
{
    var strArray = str.Distinct().ToArray();
    return new string(strArray); //字符成串
    //return string.Join(string.Empty, strArray);
}
14. 字符串反转
string ReverseStr(string str)
{
    var c=str.Reverse().ToArray();
    return new string(c);
}
static string ReverseStr(string original)
{
    char[] arr = original.ToCharArray();
    Array.Reverse(arr);
    return new string(arr);
}

15. 删除指定字符
var a=nums.Where(a=>a!=val).ToArray();
foreach (var item in a)
    Console.WriteLine(item);


16. 寻找两个正序数组的中位数
List<int> a = nums1.ToList();
List<int> b = nums2.ToList();
a.AddRange(b);
a.Sort();
>浮点数 (float)5/2=2.5||5/2=2;
 
17. 测试时间
var sw = Stopwatch.StartNew();
//-----
Console.WriteLine(sw.ElapsedMilliseconds);

18. params 参数
void UseParams(int id, params object[] list)
UseParams(2, "d", 100, 33.33, new double[] { 1.1, 2.2 });

19. DataTable取值
dt.rows[0]["列名称"].Tosring();
dt.rows[0][0].Tosring(); 表示第一行第一列的数据
DataTable.Columns.Count 获取datatable的列数
DataTable.Rows.Count 获取datatable的行数

20. 在DataSet中添加DataTable
DS.Table.Add(DT.Copy())

21. Enumerable.range()的使用
Enumerable.Range(1, 5).Select(a => a).ToArray();
var usersList = Enumerable.Range(0, 10).Select(i => new Users()
            {
                id = i ,
                name = "zhouyi",          
            });

22. 连接一个数组select,join
int[] numbers = { 2, 3, 4, 5 };
var squaredNumbers = numbers.Select(x => x * x);   
Console.WriteLine(string.Join("", squaredNumbers));
// Output:
// 4 9 16 25

23. 经典委托
List<string> names = new List<string>();
names.Add("Bruce");
names.Add("Alfred");
names.Add("Tim");
names.Add("Richard");
Action<string> test = print;
// Display the contents of the list using the Print method.
names.ForEach(print);//List输出     
void print(string name)
{
   Console.WriteLine(name);    
}

24. C#事件订阅的几种方式
方式1:常用订阅方/式
button.Click += Button_Clicked;
方式2:委托订阅方式(vS默认写法);
button.Click += new EventHandler(Button_Clicked);
方式3:委托订阅方式(最古老写法);
button.Click += delegate (object sender, EventArgs e) { textBox.Text = "Hello World!"; };
方式4:Lamda表达式订阅方式
button.Click+=(object sender, EventArgs e) => { textBox.Text = "Hello World!"; };
方式5:Lamda表达式订阅方式(参数类型可以省略)
button.Click+=(sender,e) => { textBox.Text = "Hello World!"; };

25. 反射
反射:反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中的每一个类型(包括类,结构,委托,接口和枚举)的成员和成员信息。

反射使用的命名空间:
(1)System.Reflection   (2)System.Type   (3)System.Reflection.Assembly

获取给定类型的Type引用有3种常用方式:
(1)使用C#typeof运算符
Type t = typeoff(string);
 (2)使用对象GetType()方法
string s = "sfsffgr"
(3)调用Type类的静态方法GetType()
Type t = Type.GetType("System.String");

Console.WriteLine("-----------------");
 //获取Person类中的公有字段
FieldInfo[] fis = type.GetFields();
 //获取Person类中的公有属性
PropertyInfo[] proInfo = type.GetProperties();
 //获取Person类中的构造函数
ConstructorInfo[] conInfo = type.GetConstructors();
foreach (var temp in conInfo)
{
    Console.WriteLine(temp);
    //获取构造函数的所以参数
    ParameterInfo[] parInfo = temp.GetParameters();
    foreach (var item in parInfo)
        Console.WriteLine(item);
    
}
 //获取Person类中的所有方法
MethodInfo[] methodInfo = type.GetMethods();
//根据指定的参数列表获取对应的构造函数
    Type[] paramType = new Type[2];
    paramType[0] = typeof(string);
    paramType[1] = typeof(int);
    ConstructorInfo con = type.GetConstructor(paramType);
Console.WriteLine(con);

26. async/await
async/await异步编程不能提升响应速度,但是可以提升响应能力(吞吐量)。

27. 深浅拷贝
引用类型数组是引用copy,值类型数组是深copy:
“深拷贝和浅拷贝的区别:浅拷贝主要是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝需要不但对指针进行拷贝,并对指针指向的内容进行拷贝,经过深拷贝后的指针是指向两个不同地址的指针

28. 设置验证码 英文字母和数字1-9:
private string Create_VerifCode()
{
    //定义数组,存储验证码字符(英文字母和数字0-9)
    char[] ch = new char[]
    {   '0', '1', '2', '3', '4', '5', '6','7', '8', '9',
        'a','b','c','d','e','f','g','h','i','j','k','l',
        'm','n','o','p','q','r','s','t','u','v','w','x',
        'y','z','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
        'I', 'J','K', 'L','M','N','O', 'P', 'Q', 'R', 'S',
        'T','U', 'V', 'W','X', 'Y', 'Z', '0', '1', '2',
        '3','4', '5', '6','7', '8', '9'
    };
    //使用随机数,从数组中随机抽取4个字符组成验证码
    string code = "";
    Random rand = new Random();
    for (int i = 0; i < 4; i++)
    {
        code += ch[rand.Next(0, ch.Length)];
    }
    return code;
}
29. 泛型限定条件:
 T:结构(类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型)
 T:类 (类型参数必须是引用类型,包括任何类、接口、委托或数组类型)
 T:new() (类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时new() 约束必须最后指定)
 T:<基类名> 类型参数必须是指定的基类或派生自指定的基类
 T:<接口名称> 类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
 T:U
30. 委托的又一次的理解
 void say(object name, Action<object> action)//Action<object> 是委托
{
    action(name);
}
say(1, (a) => Console.WriteLine(a));
say("zhouyi", (a) => Console.WriteLine(a+"aaa"));

31.元组,解构赋值
//tuple
var result = GetResults();
//var (x,y,z) = GetPerson();//自动推断
//var (q,_,_) = GetPerson();// 弃元(_)
Console.WriteLine(result.a);
Console.WriteLine(result.b);
Console.WriteLine(result.c);

static (string a, int b, string c) GetResults()
{
    return ("a", 1, "b");
}

32. Dotnet 序列化枚举为字符串(提炼,精简)
 https://mp.weixin.qq.com/s/0BlsFFDlKcWVTCk4ge9J2Q
using System.Text.Json;
using Newtonsoft;
var json = JsonSerializer.Serialize(new Circle()
{
    Radius = 10.1,
    BgColor = Color.LightGray
});
Console.WriteLine(json);

var a=Circle.SerializeWithStringEnum(new Circle()
{
    Radius = 10.1,
    BgColor = Color.LightGray
});
Console.WriteLine(a);
class Circle
{
    public double Radius { get; set; }
   // [JsonConverter(typeof(JsonStringEnumConverter))]
    public Color BgColor { get; set; }

    //使用一个方法装换
    public static string SerializeWithStringEnum(object obj)
    {
        var options = new JsonSerializerOptions();
        options.Converters.Add(new JsonStringEnumConverter());
        return JsonSerializer.Serialize(obj, options);
    }

    //Newtonsoft.Json
    //public static string SerializeWithStringEnumNewtonsoft(object obj)
    //{
    //    var converter = new StringEnumConverter();
    //    return JsonConvert.SerializeObject(obj, converter);
    //}
}

// [JsonConverter(typeof(JsonStringEnumConverter))]//全局的
enum Color
{
    White,LightGray,Black
}

///----------------------------------------
///webapi里面全局注册
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    });

///-----------------------------------
///标志枚举的序列化
using System.Text.Json;
using System.Text.Json.Serialization;

var colors = Color.LightGray | Color.Black;
var options =new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter());
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));//输出文本驼峰格式
var json = JsonSerializer.Serialize(new { Colors = colors },options);
Console.WriteLine(json);

[Flags]
public enum Color
{
    White = 0,
    LightGray = 1,
    Black = 2
}

//output: { "Colors":"LightGray, Black"}

/// ------------------------
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Runtime.Serialization;
//Newtonsoft 库
var converter = new StringEnumConverter();
var json = JsonConvert.SerializeObject(new TShirt
{
    Name = "男士衬衫-休闲款",
    ColorScheme = ColorScheme.WhiteBlue
}, converter);

Console.WriteLine(json);

public class TShirt
{
    public string? Name { get; set; }
    public ColorScheme ColorScheme { get; set; }
}


public enum ColorScheme
{
    [EnumMember(Value = "白/蓝")]
    WhiteBlue,

    [EnumMember(Value = "红/黑")]
    RedBlack,
}

33. C# 脚本
https://mp.weixin.qq.com/s/MvzQXh1gxe2XP_Mz7iE9Og

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;

Console.WriteLine("测试基本算数表达式:(1+2)*3/4");
var res = await CSharpScript.EvaluateAsync("(1+2)*3/4");
Console.WriteLine(@"测试字符串函数:""Hello"".Length");
var res3 = await CSharpScript.EvaluateAsync(@"""Hello"".Length");
Console.WriteLine("测试Math函数:Sqrt(2)");
//使用比较复杂的函数,可以使用WithImports引入名称空间
var res1 = await CSharpScript.EvaluateAsync("Sqrt(2)", ScriptOptions.Default.WithImports("System.Math"));
Console.WriteLine(@"测试输入输出函数:Directory.GetCurrentDirectory()");
var res2 = await CSharpScript.EvaluateAsync("Directory.GetCurrentDirectory()",
     ScriptOptions.Default.WithImports("System.IO"));
Console.WriteLine(res);
Console.WriteLine(res1);
Console.WriteLine(res2);
Console.WriteLine(res3);


999. 其他
int? i = 3;//可为空
 a= b?? 5; // b如果为空值则返回 5
sizeof(int);
string str = @"C:\Windows";//@将转义字符(\)当作普通字符对待
object obj;obj = 100; // 这是装箱
dynamic d = 20;//动态类型,可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的
int* iptr;//指针类型,指针类型变量存储另一种类型的内存地址。C# 中的指针与 C 或 C++ 中的指针有相同的功能。

//======================
int i = 75;Console.WriteLine(i.ToString());
int i; double d = 5673.74;i = (int)d;// 强制转换 double 为 int

//===============
string aa="aBd";
Console.WriteLine(aa.Length);
Console.WriteLine(aa.Contains("a"));
Console.WriteLine(aa.Equals("abd"));
Console.WriteLine(aa.ToLower());
Console.WriteLine(aa.ToUpper());
Console.WriteLine(aa.Replace("a","rrr"));
Console.WriteLine(aa.Remove(0,2));
string[] bb = {"sdfsf", "dsafd"};
posted @ 2022-04-06 16:43  cactus9  阅读(55)  评论(0编辑  收藏  举报