编辑
2025-10-05
C#
00

S7netplus 是一个开源的库,主要用于.NET环境中与西门子S7系列PLC进行通信。这个库允许开发者使用C#或其他.NET支持的编程语言来读写PLC的数据块、输入输出、标记等,非常适合于工业自动化领域的应用开发。

主要特点

  1. 易于使用:S7netplus 提供了简洁的API,使得开发者可以轻松地连接PLC,读取和写入数据。
  2. 开源:作为一个开源项目,S7netplus 允许开发者查看源代码,也欢迎社区贡献和改进。
  3. 跨平台:基于.NET平台,理论上支持所有.NET能运行的平台,包括Windows, Linux, 和 macOS。

使用S7-PLCSIM Advanced 3.0/4.0/5.0 仿真

image.png

如果启动许可证找不到,在服务中启动

image.png

注意事项

  • IP地址与子网掩码

image.png

  • 在TIA中IP修改与防真中的一样
  • 勾选Connection mechanisms中 Permit access with PUT/GET communication from remote partnet

image.png

  • 项目属性中修改 Protection 勾选Support simulation during block compilation

image.png

  • 确保Siemens PLCSIM Virtual Ethernet Adapter IP与防真IP在一个网段

image.png

  • 控制面板PG/PC
编辑
2025-10-05
C#
00

在C#这样的静态类型语言中,鸭子类型(Duck Typing)通常不像在动态语言中那样自然。鸭子类型的核心思想是:"如果它走起来像鸭子,叫起来像鸭子,那么它就是鸭子"—— 即关注对象的行为而非其类型。本文将详细介绍如何在C#中通过缓存和表达式树技术实现高性能的鸭子类型模式,以及这种模式在实际项目中的应用。

鸭子类型与C#的挑战

在传统C#开发中,我们通常通过接口来定义行为规范。但这种方式要求所有类型显式实现接口,缺乏灵活性。使用反射可以解决这个问题,但会带来严重的性能损失。那么如何在保持鸭子类型灵活性的同时,又能获得接近原生代码的性能呢?

高性能鸭子类型的三大技术支柱

我们将使用三种关键技术来实现高性能的鸭子类型:

  1. 反射:用于首次发现和识别类型的能力
  2. 表达式树:用于构建和编译高性能委托
  3. 并发缓存:存储已处理类型的委托,避免重复的反射和编译开销

完整实现案例:智能日志系统

下面我们将构建一个智能日志系统,它可以记录任何拥有GetLogMessage()方法的对象,无需这些对象实现特定接口。

核心实现

C#
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace AppDuck { public class CachedDuckTypingLogger { // 缓存委托:Type => Func<object, string> private readonly ConcurrentDictionary<Type, Func<object, string>> _messageGetterCache = new ConcurrentDictionary<Type, Func<object, string>>(); /// <summary> /// 记录任何具有GetLogMessage方法的对象 /// </summary> public void Log(object item) { try { // 获取日志消息获取器 var messageGetter = GetOrCreateMessageGetter(item.GetType()); if (messageGetter != null) { // 获取并记录消息 string message = messageGetter(item); Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}"); } else { Console.WriteLine($"[ERROR] 无法记录类型为 {item.GetType().Name} 的对象 - 未实现GetLogMessage方法"); } } catch (Exception ex) { Console.WriteLine($"[ERROR] 记录时发生异常: {ex.Message}"); } } /// <summary> /// 从缓存获取或创建消息获取委托 /// </summary> private Func<object, string> GetOrCreateMessageGetter(Type type) { return _messageGetterCache.GetOrAdd(type, t => { // 查找GetLogMessage方法 MethodInfo method = t.GetMethod("GetLogMessage", Type.EmptyTypes); if (method == null || method.ReturnType != typeof(string)) return null; // 创建表达式树 ParameterExpression param = Expression.Parameter(typeof(object), "obj"); UnaryExpression convertedParam = Expression.Convert(param, t); MethodCallExpression methodCall = Expression.Call(convertedParam, method); // 编译表达式树为委托 return Expression.Lambda<Func<object, string>>(methodCall, param).Compile(); }); } } }
编辑
2025-10-04
C#
00
编辑
2025-10-04
C#
00

本示例展示了如何在WinForms应用程序中使用ScottPlot 5.0创建一个带有十字光标的交互式图表。我们将绘制一个正弦波,并添加一个跟随鼠标移动的十字光标。

准备工作

首先,确保你已经安装了必要的NuGet包:

  • ScottPlot (5.0.x)
  • ScottPlot.WinForms (5.0.x)

完整代码

以下是完整的C#代码,包含详细注释:

C#
public partial class Form1 : Form { private FormsPlot formsPlot1; private Crosshair crosshair; private ScottPlot.Plottables.Text text; public Form1() { InitializeComponent(); SetupPlot(); } private void SetupPlot() { // 创建 FormsPlot 控件 formsPlot1 = new FormsPlot(); formsPlot1.Plot.Font.Set("SimSun"); formsPlot1.Dock = DockStyle.Fill; this.Controls.Add(formsPlot1); // 生成示例数据(正弦波) int pointCount = 1000; double[] dataX = new double[pointCount]; double[] dataY = new double[pointCount]; for (int i = 0; i < pointCount; i++) { dataX[i] = i; dataY[i] = Math.Sin(i * 0.05); } // 添加散点图 var scatter = formsPlot1.Plot.Add.Scatter(dataX, dataY); scatter.Color = Colors.Blue; scatter.MarkerSize = 0; // 不显示点标记,只显示线 // 设置轴标签 formsPlot1.Plot.XLabel("X轴"); formsPlot1.Plot.YLabel("Y轴"); formsPlot1.Plot.Title("带十字光标的正弦波图"); // 创建十字光标 crosshair = formsPlot1.Plot.Add.Crosshair(0, 0); crosshair.MarkerColor = Colors.Red; crosshair.LineWidth = 1; crosshair.LinePattern = LinePattern.Dashed; // 创建一个文本注释来显示光标位置 text = formsPlot1.Plot.Add.Text("", 10, 10); text.Alignment = Alignment.UpperLeft; text.FontSize = 14; // 添加鼠标移动事件处理器 formsPlot1.MouseMove += FormsPlot1_MouseMove; } private void FormsPlot1_MouseMove(object sender, MouseEventArgs e) { // 获取鼠标在图表坐标系中的位置 var d = formsPlot1.Plot.GetCoordinates(e.X, e.Y); // 更新十字光标位置 crosshair.X = d.X; crosshair.Y = d.Y; // 更新文本注释 text.LabelText = $"X: {d.X:F2}, Y: {d.Y:F2}"; // 请求重绘 formsPlot1.Refresh(); } }

image.png

编辑
2025-10-04
C#
00

Titanium Web Proxy是一个强大的开源.NET库,用于截获、查看和修改HTTP/HTTPS流量。本文将详细介绍如何使用Titanium Web Proxy来截获系统中的所有HTTP通信,并提供多个实用示例。

安装Titanium Web Proxy

首先,通过NuGet包管理器安装Titanium Web Proxy:

C#
Install-Package Titanium.Web.Proxy

image.png

或者在你的项目文件中添加以下引用:

XML
<PackageReference Include="Titanium.Web.Proxy" Version="3.1.1397" />