
编程语言C#
文章平均质量分 64
Talk is cheap,show me the code。
逍遥郎wj
凡读必记
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C#多层继承问题
对于DerivedClass.DisplayName()是虚方法,而SubDerivedClass.DisplayName()是重写了他的派生得最远的成员。如果使用了New修饰符的SuperSubDerivedClass.DisplayName()将被隐藏。原创 2022-06-04 13:20:14 · 640 阅读 · 1 评论 -
C#数组copy与clone的一个问题?
值类型:存在栈中,不联动随变。引用类型:存在堆中,是对引用的拷贝,联动随变。原创 2022-05-31 22:35:40 · 715 阅读 · 0 评论 -
C#语言编译:并与C/C++对比
C#语言在.NET中,编译分为两个阶段:(1) 将源代码编译为Microsoft中间语言(CIL)。(2) CLI把CIL编译为平台专用的代码。不仅是编译问题:程序执行问题C#程序还需要在一个代理(托管)的上下文中执行。 负责管理C#程序执行的代理就是:虚拟执行系统(Virtual Execution System,VES) 更通俗称呼为:“运行时”。运行时:负责加载和运行程序,并在程序执行时提供额外的服务。如下图:是C#编译执行情况。C#与C/C++...原创 2022-05-31 18:47:17 · 547 阅读 · 0 评论 -
WCF的一些坑
1、错误信息:添加服务失败。服务元数据可能无法访问。请确保服务正在运行并且正在公开元数据。原因:如果修改了接口和类的名称,那么就需要去命名空间对应的svc文件中,手动修改相应的这个值。原来的Service1不可用。同样:如果你在这里没改,那么发布之后,你需要到发布的svc文件中也修改这个名称。否则客户端还是无法访问。2、发布之前,一定要在本地编译运行没问题再发布。3、IIS无法启动端口被占用,将端口,修改为其他大于10000的号。点击启动之后:进入客户..原创 2021-12-28 22:01:19 · 852 阅读 · 0 评论 -
CSharp中Socket网络编程(七)拓展类或引申类TCPClient、TCPListener、UDPClient
TCPClient、TCPListener、UDPClient是对socket的封装和简化。见名知意TCPListener:服务端监听。TCPClient:客户端服务端参考代码://第一步: TcpListener对socket进行了一层封装,这个类里面自己会去创建socket对象。TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 10086);// 第二步:开始进行监听。listene.原创 2021-12-14 21:26:17 · 771 阅读 · 0 评论 -
CSharp中Socket网络编程(六)UDP协议编程
UDP其实并不严格区分:服务端和客户端。不过为了掩饰方便:做了简单区分。// 客户端操作// 1、创建socketSocket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);// 2、发送数据EndPoint serverPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10086);string me..原创 2021-12-14 19:59:25 · 2414 阅读 · 0 评论 -
CSharp中Socket网络编程(五)Socket状态检查与释放
clientSocket.Poll(10, SelectMode.SelectRead)如果在响应时间内有数据可供读取,则继续,否则跳出接受数据的循环。原创 2021-12-14 18:25:30 · 2472 阅读 · 0 评论 -
C# 异步多线程实现(六)资源争用与锁
多个线程同时去访问同一个变量,此时会有冲突。解决方案:锁。class MyThreadObject{ private int state = 5; public void ChangeState() { state++; if (state==5) { Console.WriteLine("state=5"); Thread.Sleep(500); } .原创 2021-12-14 17:09:39 · 1070 阅读 · 0 评论 -
C# 异步多线程实现(五)连续任务和任务层次结构
连续任务如果一个任务t1的执行是依赖于另一个任务t2的。那么就需要在这个任务t2执行完毕后才开始执行t1。这个时候我们就可以使用连续任务ContinueWith。规定了任务先后执行的关系。static void Main(string[] args){ Task t0 = new Task(DoFirst); Task t1 = t0.ContinueWith(DoSecond); Task t2 = t0.ContinueWith(DoSecond);原创 2021-12-14 14:43:33 · 274 阅读 · 0 评论 -
C# 异步多线程实现(四)Task和TaskFactory
任务Task其实是对线程做了一个封装。实例化一个Task,然后用实例化调用Start方法。 或者静态调用Run方法。此外还可以用TaskFactory类实例化执行。static void ThreadMethod(){ Console.WriteLine("任务开始"); Thread.Sleep(2000); Console.WriteLine("任务结束...");}static int ThreadMethod2(int a, int b){ re原创 2021-12-14 14:30:20 · 4663 阅读 · 0 评论 -
C# 异步多线程实现(三)线程池ThreadPool
创建线程需要时间。 如果有不同的小任务要完成,就可以事先创建许多线程,在应完成这些任务时发出请求。 这个线程数最好在需要更多的线程时增加,在需要释放资源时减少。 不需要自己创建线程池,系统已经有一个ThreadPool类管理线程。这个类会在需要时增减池中线程的线程数,直到达到最大的线程数。池中的最大线程数时可配置的。 在双核CPU中,默认设置为1023个工作线程和1000个I/O 线程(文件等)。 也可以指定在创建线程池时应立即启动的最小线程数,以及线程池中...原创 2021-12-14 11:23:44 · 759 阅读 · 0 评论 -
C# 异步多线程实现(二)Thread类
C# 异步多线程实现(二)Thread类原创 2021-12-14 11:16:50 · 1106 阅读 · 0 评论 -
C# 异步多线程实现(一)异步委托——Action和Func
异步多线程实现:异步委托:Action和Func。调用BeginInvoke,开启线程。原创 2021-12-14 11:08:21 · 5830 阅读 · 0 评论 -
静态字段承担全局变量的一个例子
目标:每新建一个实例都自动分配累加ID。原创 2021-12-03 10:45:06 · 225 阅读 · 0 评论 -
C#函数返回多个值的做法
C#返回多个值的办法。原创 2021-11-30 20:47:12 · 4432 阅读 · 0 评论 -
值类型与引用类型
一个类型要么是值类型,要么是引用类型。区别在于拷贝方式:值类型的数据总是拷贝值;内存拷贝; 而引用类型的数据总是拷贝引用。引用拷贝;值类型值类型直接包含值:在内存中,直接开辟空间,存储值。数据存在内存栈(stack)中。换言之,变量引用的位置就是内存中实际存储值的位置。因此,将一个值赋值给变量1,再将变量1赋值给变量2,会在变量2的内存位置创建值的拷贝,而不是引用变量1的位置。这进一步造成更变变量1的值不会影响变量2的值。int a = 3;int b = a;.原创 2021-11-30 12:36:23 · 827 阅读 · 0 评论 -
String 和 StringBuilder 类型
尽管StringBuilder和String都表示字符序列,但它们的实现方式不同。String是不可变类型。也就是说,出现的用于修改对象的每个操作String实际上都会创建一个新的字符串。翻译 2021-06-01 22:54:53 · 401 阅读 · 0 评论 -
CSharp中进程与线程入门
进程:每一个应用程序都可以看做是一个进程。1、进程在C#中操作进程的类叫做:Processstatic void Main(string[] args) { // 获取当前所有正在运行的进程 //Process[] pros = Process.GetProcesses(); //foreach (var item in pros) //{ // //原创 2021-03-03 17:36:49 · 1273 阅读 · 0 评论 -
CSharp中Socket网络编程(一)过程梳理
人与人之间通过【电话】来通信;程序之间通过【Socket】来通信;电话之间规定好【语言】:电脑与电脑之间通信规定好:【协议】。套接字就是程序间的电话机。IP地址和端口号。每一台服务器至少有一个IP地址,每一个进程程序都有一个端口。不同应用程序,端口号不同。客户端通过端口找到服务器端口。应用程序通信建立。负责监听的Socket,收到通信请求后,创建一个负责通信的Socket。这个连接通信中有两种协议:TCP/UDP;TCP:安全、稳定、不易发生数据丢失;三次握手:必须有服务器.原创 2021-03-05 09:29:41 · 4419 阅读 · 4 评论 -
CSharp中Socket网络编程(二)重要bug修改
第一部分:整个通信过程梳理;文末附全套代码;本篇为第二部分:重要bug完善;第三部分:消息类型编码:自定义通信协议。在第一部分:整个通信过程梳理中:有一个重要bug:多个客户端与服务器通信,服务器发送的消息只能被最新接入的客户端收到,其他客户端无法收到。不能实现点对点,端到端的通信。为此在服务端我们预留了一个下拉列表来选择通信目标端。思路是:...原创 2021-03-08 18:55:07 · 660 阅读 · 1 评论 -
CSharp中Socket网络编程(三)自定义通信传输协议
通信协议这事:我们希望在通信中除了传输信息以外,还可以发送图片,还可以实现窗口震动。此时涉及发送数据的类型问题。对于接收方来说,并不知道发送方发送出来的格式,因此如果按照原来解码为字符串类型则不再适用。这事需要双方事先约定好。发送以0开头的字节数组代表字符串类型,发送以1开头的字节数组代表文件,发送以2开头的字节数组代表震动。0:发送消息:我们原来的代码如此。点击按钮,直接将对话框中的文本转为字节流发送。private void btnSend_Click(object sender,原创 2021-03-08 21:31:33 · 1686 阅读 · 0 评论 -
CSharp中Socket网络编程(四)全部代码附UI图
第一部分:整个通信过程梳理;文末附全套代码;第二部分:重要bug完善;第三部分:消息类型编码:自定义通信协议。本篇为第四部分:全套代码原创 2021-03-09 13:50:01 · 1275 阅读 · 1 评论 -
CSharp中委托(一)委托、匿名函数、lambda表达式、多播委托、窗体传值、泛型委托
委托先来个例子:三个需求:1、将一个字符串数组中每个元素都转换成大写2、将一个字符串数组中每个元素都转换成小写3、将一个字符串数组中每个元素两边都加上 双引号string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyZ" };//StrToLower(names);StrToUpper(names);//StrSYH(names);for (int i = 0; i < names.Length; i++){原创 2021-03-10 20:59:59 · 1419 阅读 · 0 评论 -
C#学习笔记(一)静态与非静态
静态非静态区别;using System;using System.Collections.Generic;using System.Text;namespace _04面向对象03静态与非静态的区别{ // 先添加public;如果添加static就是静态类,如果不添加static就是非静态类。 // 静态和非静态的区别: // 1、在非静态类中,既可以有非静态成员,又可以有静态成员。静态类中,只能包含静态成员。 // 2、在调用实例成员的时候,需要使用对.原创 2021-03-13 17:59:34 · 375 阅读 · 0 评论 -
C#学习笔记(二)方法之定义(内存堆栈)
定义一个Student类。class Student{ public int ID; public string Name;}在Main()中调用。Student stu = new Student();Console.WriteLine(stu.ID);Console.WriteLine(stu.Name);这对括号就是在调用Student 实例 的构造器。但是我们的类定义时:没有构造器。编译器会自动准备一个默认的构造器。如何判断默认的构造器执.原创 2021-03-26 09:51:35 · 252 阅读 · 1 评论 -
C#学习笔记(三)方法之重载
声明带有重载的方法:方法签名(method signature)由方法的名称、类型形参的个数和它的每一个形参(按从左到右的顺序)的类型和种类(值、引用或输出)组成。方法签名不包含返回值类型。 类型形参:方法函数的后面。 public int Add<T>(int a, int b){ T t; //... return a+b;} 参数的种类:三种参数变量:传值的、传输出的(out)、传引用的(ref)。 实例构造函数签名由它的每一个形参(原创 2021-03-26 10:12:01 · 152 阅读 · 0 评论 -
C#学习笔记(四)方法的调用与栈的关系
方法调用时栈内存的分配调用:对Stack frame的分析:Stack Frame:一个方法在调用的时候在栈内存中的布局。class Program{ static void Main(string[] args) { double result = Calculator.GetConeVolume(100, 80); }}class Calculator{ public static double GetCircleArea(d原创 2021-03-27 16:07:08 · 1067 阅读 · 3 评论 -
C#学习笔记(五)CSharp操作符-基本操作符(一)
表达式和语句都是为方法服务的。操作符 + 操作数 组成 表达式;表达式后面加分号;组成语句。语句则是为了组成方法体。操作符也叫作运算符:operator。操作数:operand操作符不能脱离与它相关联的数据类型。int x = 5;int y = 4;Console.WriteLine(x/y); // 1double a = 5.0;double b = 4.0;Console.WriteLine(a/b); //1.25为什么要发明运算符?原创 2021-03-28 00:28:31 · 2943 阅读 · 0 评论 -
C#学习笔记(六)CSharp操作符-基本操作符(二)new
new在CSharp中不仅仅是关键字,其实它本质也是一个操作符。new操作符:1、帮助我们在内存中创建一个类型的实例,2、并且立即调用这个类型的实例构造器instance constructor。3、如果new操作符的左边有赋值符号的话,还可以得到实例的内存地址,并且把地址通过赋值符号交给负责访问这个实例的变量。Form myForm = new Form();new的第一个功能:在内存中创建一个类型的实例:new Form创建一个类型的实例;new的第二个功能:立即调用原创 2021-03-28 11:21:13 · 1161 阅读 · 0 评论 -
C#学习笔记(七)CSharp操作符-基本操作符(三)
checked与unchecked:检查一个值在内存中是否有溢出。C#语言是一种强类型语言。任何一个变量在内存中都是有数据类型的。数据类型有一个非常重要的标识:类型在内存中所占空间的大小。一旦一个变量在内存中超过了它定义的内存空间,是否需要去检查。就要由checked和unchecked来操作。static void Main(string[] args){ uint x = uint.MaxValue; Console.WriteLine(x); string binS原创 2021-03-28 14:18:46 · 622 阅读 · 0 评论 -
C#学习笔记(八)CSharp操作符-一元操作符
一元操作符:只能操作一个操作数。+ - ! ~ ++x --x (T)x await &x *x最不常用的就是&x取地址操作符和引用操作符*x。上一节我们定义的Student结构体:Student* pStu = &stu;取地址之后赋值给一个指针变量。指针变量定义:类名后跟星号*空格变量名。通过引用操作符也可以直接拿到对象。此时就可以用点来操作。之前用指针地址只能用指向操作符。但是点这个操作符也就是成员访问操作符...原创 2021-03-28 16:55:47 · 1016 阅读 · 0 评论 -
C#学习笔记(九)CSharp表达式与语句(一)
表达式操作数的值VS表达式的值。int x = 90;Console.WriteLine(x++);// 90Console.WriteLine(x);// 91int x = 90;Console.WriteLine(++x);// 91Console.WriteLine(x);// 91每一种算数运算符没有发生数值提升的时候,返回值类型与运算数类型相同。赋值表达式的值:int x = 90;int y;Console.WriteLine(y=x);Con.原创 2021-03-28 17:51:01 · 377 阅读 · 0 评论 -
C#学习笔记(十)CSharp表达式与语句(二)ildasm打开反编译器+foreach本质
语句Statements.语句等价于一个或一组有明显逻辑关联的指令。在汇编语言的书《Assembly Language step by step》中有一句话:像Pascal或者C++这类语言的编译器的功能:就是去决策如何把给定的一些语句翻译成一系列的机器语言的指令。如何查看Csharp编译后的低级汇编语言:右键【项目名称】选择【在文件资源管理器中打开文件夹】中,选择【bin】下【Debug】下的exe文件。将应用文件复制到桌面。然后子【win】中搜索visualStu..原创 2021-03-30 16:29:29 · 1551 阅读 · 0 评论 -
C#学习笔记(十一)字段、属性、索引器、常量
字段、属性、索引器、常量:这四者放在一起:因为它们都表达数据。一个程序的本质就是:数据+算法。C#的类型成员:类或者结构体。1、字段定义:字段(field)是一种表示与对象或类型(类与结构体)关联的变量。定义中的两个关键字:对象 或者 类型。那么可以把字段分为两类:与对象关联的字段:实例字段,因为对象是实例化出来的。表述每个对象个体的差异性。 与类型关联的字段:静态字段,由static修饰的,静止的。表述整个类的族群特性。一个可适用于不同个体对象的差异性,实例化不同对象...原创 2021-04-02 09:06:50 · 574 阅读 · 0 评论 -
C#学习笔记(十二)参数:传值、输出、引用、数组、具名、可选参数、可选方法
参数是方法的一部分。传值参数:参数的默认传递方式。 输出参数:用于除返回值外还需输出的场景。 引用参数:用于需要修改实际参数值的场景。 数组参数:用于简化方法的调用。 具名参数:提高可读性。 可选参数:参数拥有默认值。 扩展方法(this参数):为目标数据类型“追加”方法。1、传值参数:值类型作用域为当前方法:初始值为该方法调用时所赋给他的实参。2、传值参数:引用类型,并且新创建对象引用类型的变量:存储的值是一个地址。指向在堆内存中的数据。即:引用类型的变量的值存储的原创 2021-04-02 18:00:37 · 747 阅读 · 0 评论 -
C#学习笔记(十三)委托——一切皆地址
委托(delegate)是函数指针的“升级版”。C/C++中的函数指针。C语言中的函数指针:#include<stdio.h>// 声明函数指针,定义为一种数据类型。typedef int (*Calc)(int a, int b);int Add(int a, int b){ int result = a + b; return result;}int Sub(int a, int b){ int result = a - b; return resu原创 2021-04-06 17:12:04 · 665 阅读 · 2 评论 -
C#学习笔记(十四)事件(一)通知
定义:定义:单词:Event,翻译为“事件”。《牛津词典》中的解释:“a thing that happens, especially something important”。通顺的解释就是:能够发生的什么事情。如果一个作为主语的名词可以使用发生这个词来作为的他的谓语动词的话,那么这个名词就是个事件。举个栗子:拿苹果作为主语,谓语动词就不能是发生。但如果是苹果新机发布,或者说苹果公司上市作为主语的话,他们都是可以发生的,也就是说他们都是事件。也就是说是以公司为主体的上市,和以新机为..原创 2021-04-07 11:36:31 · 1726 阅读 · 0 评论 -
C#学习笔记(十五)事件(二)事件模型;添加Forms引用;
事件模型的五个组成部分:1、事件的拥有者(event source,对象)2、事件成员(event,成员)3、事件的响应者(event subscriber,对象)4、事件处理器(event handler,成员)——本质上是一个回调方法5、事件订阅——把事件处理器与事件关联在一起,本质上是一种以委托类型为基础的“约定”。事件订阅解决了三个问题:1、当一个事件发生的时候,事件的拥有者都会通知谁,或者都有谁会被通知到。被通知到的对象一定是订阅了这个事件的对象。2、拿什么方原创 2021-04-08 15:42:44 · 1068 阅读 · 0 评论 -
C#学习笔记(十七)事件(四)事件个人总结
若要写一个事件:首先要明确:一个完整的事件由五部分组成:事件拥有者、事件、事件响应者、事件处理器、订阅。用C#来写原创 2021-04-10 17:11:27 · 609 阅读 · 1 评论 -
C#学习笔记(十六)事件(三)自定义事件+事件不是委托
一、自定义事件的完整声明方式餐馆点餐Order这样一个事件:服务员拿自己的一个事件处理器来订阅顾客点餐这样一个事件。顾客的点餐这个事件一发生,服务员的事件处理器就会马上执行。如何自定义一个事件?首先考虑构成事件的五个部分:事件拥有者,事件,事件响应者,事件处理器,订阅。第一步:定义一个事件拥有者。Customer类,他会有一个属性:账单Bill。一个方法:PayTheBill。class Customer{ public double Bill { get; set; }原创 2021-04-11 09:34:43 · 1036 阅读 · 0 评论