Skip to content

Commit

Permalink
Merge pull request #6 from ffengc/rookie-dev
Browse files Browse the repository at this point in the history
feat collections part, csharp containers
  • Loading branch information
ffengc authored Aug 9, 2024
2 parents fef6a85 + 26868a9 commit 92e1d4e
Show file tree
Hide file tree
Showing 27 changed files with 272 additions and 14 deletions.
Binary file modified .vs/ProjectEvaluation/rookie-csharp.metadata.v8.bin
Binary file not shown.
Binary file modified .vs/ProjectEvaluation/rookie-csharp.projects.v8.bin
Binary file not shown.
Binary file modified .vs/ProjectEvaluation/rookie-csharp.strings.v8.bin
Binary file not shown.
Binary file modified .vs/rookie-csharp/DesignTimeBuild/.dtbcache.v2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified .vs/rookie-csharp/v17/.futdcache.v2
Binary file not shown.
Binary file modified .vs/rookie-csharp/v17/.suo
Binary file not shown.
21 changes: 10 additions & 11 deletions .vs/rookie-csharp/v17/DocumentLayout.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"WorkspaceRootPath": "C:\\Users\\demac\\Desktop\\rookie-csharp\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{699C2EF6-C0D4-400D-88E4-D56BB71B68E3}|rookie-csharp.csproj|c:\\users\\demac\\desktop\\rookie-csharp\\src\\lesson4.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{699C2EF6-C0D4-400D-88E4-D56BB71B68E3}|rookie-csharp.csproj|solutionrelative:src\\lesson4.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{699C2EF6-C0D4-400D-88E4-D56BB71B68E3}|rookie-csharp.csproj|c:\\users\\demac\\desktop\\rookie-csharp\\src\\lesson5.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{699C2EF6-C0D4-400D-88E4-D56BB71B68E3}|rookie-csharp.csproj|solutionrelative:src\\lesson5.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{699C2EF6-C0D4-400D-88E4-D56BB71B68E3}|rookie-csharp.csproj|c:\\users\\demac\\desktop\\rookie-csharp\\main.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
Expand All @@ -31,20 +31,19 @@
"ViewState": "AQIAAAkAAAAAAAAAAAAAABcAAAATAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-02T15:31:06.637Z",
"IsPinned": true,
"EditorCaption": ""
"IsPinned": true
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "Lesson4.cs",
"DocumentMoniker": "C:\\Users\\demac\\Desktop\\rookie-csharp\\src\\Lesson4.cs",
"RelativeDocumentMoniker": "src\\Lesson4.cs",
"ToolTip": "C:\\Users\\demac\\Desktop\\rookie-csharp\\src\\Lesson4.cs",
"RelativeToolTip": "src\\Lesson4.cs",
"ViewState": "AQIAACoAAAAAAAAAAAAAADsAAAAJAAAA",
"Title": "Lesson5.cs",
"DocumentMoniker": "C:\\Users\\demac\\Desktop\\rookie-csharp\\src\\Lesson5.cs",
"RelativeDocumentMoniker": "src\\Lesson5.cs",
"ToolTip": "C:\\Users\\demac\\Desktop\\rookie-csharp\\src\\Lesson5.cs",
"RelativeToolTip": "src\\Lesson5.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAALoAAAATAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-05T07:07:08.679Z",
"WhenOpened": "2024-08-08T14:45:01.523Z",
"EditorCaption": ""
}
]
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1489,3 +1489,20 @@ public void Test4()
## 文件处理

略,这里不赘述了,使用的时候直接看文档即可。

## `System.Collections`容器

**这一部分参考:[https://gitee.com/chutianshu1981/AwesomeUnityTutorial/](https://gitee.com/chutianshu1981/AwesomeUnityTutorial/)**

其实就是 C# 版本的STL。

`System.Collections` 包含非泛型容器类

`System.Collections.Generic` 包含泛型容器类

自 `.NET Framework 4` 起,`System.Collections.Concurrent` 命名空间中的集合可提供高效的线程安全操作,以便从多个线程访问集合项。 `System.Collections.Immutable` 命名空间(`NuGet` 包)中的不可变集合类本质上就是线程安全的,因为操作在原始集合的副本上进行且不能修改原始集合。

很多容器和方法和C++是同样思想的,都是数据结构的封装,使用的区别有但不大。

具体可以见代码 `src/Lesson5.cs`。

2 changes: 1 addition & 1 deletion index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class Run
{
static void Main(string[] args)
{
Lesson4 t = new Lesson4();
t.Test4();
Lesson5 t = new Lesson5();
t.Test2();
}
}
}
Binary file modified obj/Debug/net8.0/apphost.exe
Binary file not shown.
23 changes: 23 additions & 0 deletions obj/Debug/net8.0/rookie-csharp.AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Reflection;

[assembly: System.Reflection.AssemblyCompanyAttribute("rookie-csharp")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+49656665a134f9b482fb1624ef6a184ab0778121")]
[assembly: System.Reflection.AssemblyProductAttribute("rookie-csharp")]
[assembly: System.Reflection.AssemblyTitleAttribute("rookie-csharp")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

// Generated by the MSBuild WriteCodeFragment class.

1 change: 1 addition & 0 deletions obj/Debug/net8.0/rookie-csharp.AssemblyInfoInputs.cache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18da16fe19856f7bbc4062ec35de085f73d7fcdad310d64651ccb2d89fa0773d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
is_global = true
build_property.TargetFramework = net8.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = rookie_csharp
build_property.ProjectDir = C:\Users\demac\Desktop\rookie-csharp\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
Binary file modified obj/Debug/net8.0/rookie-csharp.assets.cache
Binary file not shown.
8 changes: 8 additions & 0 deletions obj/project.nuget.cache
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"version": 2,
"dgSpecHash": "4i9ZN8UnAWE=",
"success": true,
"projectFilePath": "C:\\Users\\demac\\Desktop\\rookie-csharp\\rookie-csharp.csproj",
"expectedPackageFiles": [],
"logs": []
}
197 changes: 197 additions & 0 deletions src/Lesson5.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections;
using System.Globalization;
using System.Runtime.CompilerServices;

internal class Lesson5
{
public void ShowList<T>(T container)
{
// 处理 IEnumerable<T> 类型的容器,如 List<T>, Stack<T>, Queue<T>
if (container is IEnumerable enumerable)
{
foreach (var item in enumerable)
{
Console.Write(item + " ");
}
}
// 处理 Dictionary<TKey, TValue> 类型的容器
else if (container is IDictionary dictionary)
{
foreach (DictionaryEntry entry in dictionary)
{
Console.Write($"[{entry.Key}, {entry.Value}] ");
}
}
else
{
Console.WriteLine("Unsupported container type.");
return;
}
Console.WriteLine();
}
public void Test1()
{
// C# 的 List 相当于 std::vector
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.list-1?view=net-8.0
List<int> lst = new List<int>(new int[] { 1, 3, 5, 7, 9 });
ShowList(lst);
var pos1 = lst.Find(x => x == 7); // List<T>中的Find方法用于查找满足条件的元素,但要传递一个谓词(predicate)来进行查找
Console.WriteLine(pos1); // 这里直接是int类型了
// LinkedList 相当于 std::list
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.linkedlist-1?view=net-8.0
LinkedList<int> link_lst = new LinkedList<int>(new int[] { 1, 3, 5, 7, 9 });
link_lst.AddLast(10);
link_lst.AddFirst(-1);
ShowList(link_lst);
var pos2 = link_lst.Find(20); // 这里返回的是一个节点
if (pos2 != null)
Console.WriteLine(pos2.Value);
else
Console.WriteLine("cannot find");
// size
Console.WriteLine(link_lst.Count);
Console.WriteLine(link_lst.First.Value); // first node
Console.WriteLine(link_lst.Last.Value); // last node
}
public void Test2()
{
// Stack / C++ std::stack
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.stack-1?view=net-8.0
Stack<int> st = new Stack<int>();
st.Push(1);
st.Push(2);
st.Push(3);
st.Push(4);
while (st.Count > 0)
{
var num = st.First();
st.Pop();
Console.Write(num + " ");
}
Console.WriteLine();
st.Clear();
Console.WriteLine(st.Count);
// Queue / C++ std::queue
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.queue-1?view=net-8.0
Queue<int> q1 = new Queue<int>(new int[] { 1, 2, 3, 4, 5 });
Queue<int> q2 = new Queue<int>(Enumerable.Range(1, 5));
Console.WriteLine(q1 == q2); // false 比较的不是内容,而是两个队列的引用
Console.WriteLine(q1.SequenceEqual(q2));
q1.Clear();
Console.WriteLine(q1.Count);
// PriorityQueue / C++ std::priority_queue
// PriorityQueue 的第二个类型参数应该是优先级
// : 第一个数字是存储的数据来的,不参与排序,第二个数字是用来排序的数字
// 不能直接批量初始化,但是可以手动写一个方法
// 使用扩展方法简化初始化
PriorityQueue<int, int> pq = new PriorityQueue<int, int>().Initialize((1, 3), (2, 1), (3, 2));
ShowList(pq); // error 不能迭代器访问
while (pq.Count > 0)
{
int task = pq.Dequeue();
Console.WriteLine(task);
}
}
public void Test3()
{
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.dictionary-2?view=net-8.0
// Dictionary<k, v> --> hastable / C++ std::unordered_map
Dictionary<int, string> map1 = new Dictionary<int, string>();
// Add(Tkey,TValue) 将指定的键和值添加到字典中
map1.Add(1, "hello world");
map1.TryAdd(1, "hello world, test"); // will return false
map1.Add(2, "hello linux");
ShowList(map1);
Dictionary<int, string> map2 = new Dictionary<int, string>();
map2.Add(1, "hello world1");
map2.Add(2, "hello linux1");
// Compare 属性 可以用来看key是如何比较的
var comp = map1.Comparer;
Console.WriteLine(comp.ToString());
// Count属性
Console.WriteLine(map1.Count);
// []访问数据
Console.WriteLine(map2[1]);
// .Keys获取所有的键
var res = map1.Keys;
foreach (var key in res) Console.Write(key + " ");
Console.WriteLine();
// .Values获取所有的值
var res2 = map1.Values;
foreach (var v in res2) Console.Write(v + " ");
Console.WriteLine();
// Clear() 将所有键和值从 Dictionary<TKey,TValue> 中移除
map2.Clear();
Console.WriteLine(map2.Count);
// ContainsKey(TKey) :确定是否 Dictionary<TKey,TValue> 包含指定键
Console.WriteLine(map1.ContainsKey(1));
Console.WriteLine(map1.ContainsKey(3));
// ContainsValue(TValue) 确定 Dictionary<TKey, TValue> 是否包含特定值, 效率比较低,建议尽可能使用前一个方法
// 找key可以O(1), 但是找值需要线性查找
// Remove(TKey) 从 Dictionary<TKey, TValue> 中移除所指定的键的值
// Remove(TKey, TValue) 从 Dictionary<TKey,TValue> 中删除具有指定键的值,并将元素复制到 value 参数
}
public void Test4()
{
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.sorteddictionary-2?view=net-8.0
// SortedDictionary<TKey,TValue> red-black tree / C++ std::map
// 基本操作和 Dictionary<k, v> 相同
SortedDictionary<int, int> map = new SortedDictionary<int, int> { { 1, 2 }, { 2, 3 }, { 3, 4 }, { -1, 2 } };
ShowList(map);
}
public void Test5()
{
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.sortedlist-2?view=net-8.0
// SortedList<TKey,TValue> 底层是数组实现的,操作基本上和SortedDictionary/Dictionary相同
SortedList<int, int> lst = new SortedList<int, int> { { 1, 2 }, { 2, 3 }, { 3, 4 }, { -1, 2 } };
ShowList(lst);
}
public void Test6()
{
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.hashset-1?view=net-8.0
// HashSet / C++ std::unordered_set
// 和Dictionary操作类似
HashSet<int> s = new HashSet<int>(new int[] { 1, 3, 5, 7, 9, 2, 4, 6 });
ShowList(s);
// 提供了数学集运算
HashSet<int> s2 = new HashSet<int>(new int[] { -1, 1, -2, 2 });
// Union
var res = s2.Union(s);
foreach (int i in res) { Console.Write(i + " "); }
Console.WriteLine();
// IntersectWith
res = s2.Intersect(s);
foreach (int i in res) { Console.Write(i + " "); }
Console.WriteLine();
// ExceptWith
s2.ExceptWith(s);
ShowList(s2);
// SymmetricExceptWith
s2.SymmetricExceptWith(s);
ShowList(s2);
}
public void Test7()
{
// doc: https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.sortedset-1?view=net-8.0
// SortedSet / C++ std::set
SortedSet<int> s = new SortedSet<int>(new int[] { 1, 3, 5, 7, 9, 2, 4, 6 });
ShowList(s); // sorted result
}
}
public static class PriorityQueueExtensions
{
public static PriorityQueue<TElement, TPriority> Initialize<TElement, TPriority>(
this PriorityQueue<TElement, TPriority> pq,
params (TElement element, TPriority priority)[] items) // 第一个参数是this指针
{
foreach (var item in items)
pq.Enqueue(item.element, item.priority);
return pq;
}
}

0 comments on commit 92e1d4e

Please sign in to comment.