c#学习笔记

1|0PInvoke互操作技术

1|1代码编写

  • c++编写
--- Person.cpp extern "C" { _declspec(dllexport) int Sum(int a, int b); } --- Person.h #include "Person.h" #include "iostream" using namespace std; int Sum(int a, int b) { return a + b; }
  • c#调用
class Program { [DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl)] extern static int Sum(int a, int b); static void Main(string[] args) { var result = Sum(10, 20); Console.WriteLine($"10+20={result}"); Console.ReadLine(); } } ---- output ----- 10+20=30
  • c#编写,c++调用
--- main.cs class Program { delegate void Callback(int a); [DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl)] extern static void AsyncProcess(Callback callback); static void Main(string[] args) { AsyncProcess((i) => { //这里回调函数哦... Console.WriteLine($"这是回调函数哦: {i}"); }); Console.ReadLine(); } } ------- output ------- 这是回调函数哦: 10 --- Person.cpp extern "C" { //函数指针 typedef void(_stdcall* PCALLBACK) (int result); _declspec(dllexport) void AsyncProcess(PCALLBACK ptr); } --- Person.h #include "Person.h" #include "iostream" using namespace std; void AsyncProcess(PCALLBACK ptr) { ptr(10); //回调C#的委托 }
  • 传入c++里的内存由c#的垃圾回收器负责释放

  • 当 C++ 函数在堆上分配内存时,内存的释放责任由调用者负责,而不是由 C++ 函数本身负责

1|2环境配置

  • 用vs2019创建C++的Console App,修改两个配置: 将程序导出为dll,修改成compile方式为Compile as C++ Code (/TP)

2|0c#访问控制

  • c#中的成员函数、变量必须保持与类前定义权限一致,与c++相比,必须在类前加访问控制

2|1一般情况(4种)

  • public:public关键字表示类成员对外部代码是完全可见和可访问的。即其他类或代码可以直接访问标记为public的成员。这是最开放的访问级别
  • private:private关键字表示类成员只能在当前类内部访问,其他类无法访问标记为private的成员。这实现了数据隐藏和封装,确保类的实现细节对外部代码是不可见的
  • protected:protected关键字表示类成员只能在当前类内部和其子类中访问。这允许继承体系中的子类访问基类的受保护成员,但对于其他类仍然是不可见的
  • internal:internal关键字表示类成员只能在当前程序集内部访问。这个访问级别对于模块化代码和库的内部实现很有用,它允许不同的程序集使用相同的internal成员,但对于其他程序集是不可见的

2|2特殊情况(2种)

  • protected internal:protected internal关键字表示类成员可以在当前程序集内部和其子类中访问。它是protected和internal的结合,对于继承体系中的子类和同一程序集的其他类都是可见的。
  • private protected:private protected关键字表示类成员可以在同一程序集内部和其派生类中访问,但是对于其他程序集的类是不可见的。它是private和protected的结合

3|0c#标准

3|1c++ & c# 数据结构对比

c++ c #
vector List
map SortedDictionary<TKey, TValue>
set HashSet
queue Queue
stack Stack
priority_queue PriorityQueue
deque LinkedList
unordered_map Dictionary<TKey, TValue>

3|2c#语法

  • 更改字符串的值
char[] chs= s.ToCharArray(); chs[3] = '小'; s = new string(chs);
  • enum
public enum NGType { 拔针不良 = 10, 极耳错位 = 1, 极耳NG = 2, 读码NG=3, 外观AI不良=4 } /// idx访问(按排列 不按val) for(int i = 0; i < 5; ++i) Console.WriteLine("{0}\t", (NGType)i); int idx = 1; // output: 拔针不良 极耳错位 极耳NG 读码NG 外观AI不良
  • io相关
// Environment.CurrentDirectory; string currentDir = Environment.CurrentDirectory; Console.WriteLine("Current directory: " + currentDir); // 设置当前工作目录 string newDir = @"C:\Temp"; Environment.CurrentDirectory = newDir; Console.WriteLine("New current directory: " + Environment.CurrentDirectory); // 在新的工作目录下读取文件(假设 C:\Temp 目录下有一个 test.txt 文件) string filePath = "test.txt"; string fullPath = System.IO.Path.Combine(Environment.CurrentDirectory, filePath); string content = System.IO.File.ReadAllText(fullPath); Console.WriteLine("File content: " + content); // FileInfo // 文件路径 string filePath = @"C:\Temp\example.txt"; // 实例化 FileInfo 对象 FileInfo fileInfo = new FileInfo(filePath); // 获取文件信息 Console.WriteLine("File Name: " + fileInfo.Name); Console.WriteLine("File Full Path: " + fileInfo.FullName); Console.WriteLine("Directory: " + fileInfo.Directory); Console.WriteLine("File Size: " + fileInfo.Length + " bytes"); Console.WriteLine("Creation Time: " + fileInfo.CreationTime); Console.WriteLine("Last Write Time: " + fileInfo.LastWriteTime); // 文件复制和移动 string destinationPath = @"C:\Temp\newExample.txt"; fileInfo.CopyTo(destinationPath, true); // true 表示如果目标文件存在,则覆盖 fileInfo.MoveTo(@"C:\Temp\MovedExample.txt"); // 文件删除 fileInfo.Delete();
  • 委托 delegate
    • 可以让你将方法作为参数传递给其他方法,或者在特定条件下执行多个方法
// 委托类型声明 delegate int MyDelegate(int x, int y); // 创建委托实例,并绑定方法 MyDelegate myDelegate = new MyDelegate(Add); int result = myDelegate(5, 10); // 调用委托实例,执行绑定的方法 Console.WriteLine("Addition Result: " + result); // 绑定多个方法,创建委托链 myDelegate += Subtract; myDelegate += Multiply; myDelegate += Divide; // 调用委托链,依次执行绑定的方法 result = myDelegate(20, 5); Console.WriteLine("Result of Delegate Chain: " + result);
  • System.Text.StringBuilder
    • 相当于c++里的string
System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet"); sb[0] = 'C'; System.Console.WriteLine(sb.ToString()); //Outputs Cat: the ideal pet
  • enum遍历
foreach (DaysOfWeek day in Enum.GetValues(typeof(DaysOfWeek))) { Console.WriteLine($"{day}: {(int)day}"); }
  • get,set自定义逻辑获值赋值
public class Person { private string name; public string Name { get { return name; } set { // 可以在 set 方法中加入逻辑,例如验证输入值是否合法 if (!string.IsNullOrEmpty(value)) { name = value; } else { Console.WriteLine("Name cannot be empty."); } } } }
  • GC(Garbage Collection)

    • 是.NET Framework(或.NET Core)中的一种自动内存管理机制,它负责自动回收不再使用的内存,并释放给操作系统。以下是.NET Framework 中的常见 GC 过程:

      • 标记阶段(Marking Phase):GC 会从根对象开始,通过遍历对象图(Object Graph)来标记所有可达的对象。根对象包括全局变量、静态变量以及当前线程的栈上的变量。所有可达的对象会被标记为“存活”。

      • 清理阶段(Sweeping Phase):在标记阶段后,GC 会扫描堆中的所有对象,清理未被标记的对象。未被标记的对象被认为是“垃圾”,会被回收。

      • 压缩阶段(Compacting Phase):在清理阶段后,GC 会对堆中的存活对象进行压缩,将它们移动到一侧,从而使得堆空间变得更加连续,减少内存碎片化问题。

      • 释放阶段(Release Phase):在压缩阶段后,GC 会将不再使用的堆内存释放给操作系统,使得这些内存可以被其他进程或应用程序使用。

    • GC 过程是非常复杂的,并且.NET Framework 提供了不同的 GC 实现(如标记-清除、标记-压缩、并发 GC 等),以适应不同的场景和需求

  • 泛型

    • 类似与c++的模板类
// Declare the generic class. public class GenericList<T> { public void Add(T input) { } }

__EOF__

本文作者InsiApple
本文链接https://www.cnblogs.com/InsiApple/p/17570593.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   InsiApple  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示