.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.序列化对象
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"};