你有没有遇到过这种情况:
上一节刚创建了第一个控制台项目,兴冲冲往里面加代码。没几天,同事说"把报警模块单独拆出来",你打开资源管理器,愣了——这个 .cs 文件到底该放哪?新建一个项目?还是直接加文件?
这个问题,99% 的初学者都踩过。
搞清楚 解决方案(Solution)、项目(Project)、文件(File) 这三层关系,你就不会再乱了。
「上一节我们学了如何在 VS2026 中创建第一个 C# 控制台项目,掌握了从新建到运行的基本流程。今天在这个基础上,我们进一步学习这个项目背后的"工程结构"——解决方案、项目、文件是怎么组织在一起的。」
你在工厂管过物料仓库吗?
整个仓库叫仓储中心,里面分了几个库房,每个库房里摆着一排排货架和物料。
VS2026 的工程结构,和这个逻辑一模一样:
| 工厂类比 | VS概念 | 文件扩展名 |
|---|---|---|
| 仓储中心 | 解决方案(Solution) | .sln |
| 库房 | 项目(Project) | .csproj |
| 物料/货架 | 文件(File) | .cs / .xaml 等 |
「一个解决方案可以包含多个项目,一个项目可以包含多个文件。这是 C# 工程的基本骨架。」
解决方案(Solution,读作"索鲁申")是整个工程的"总包"。
它本身不写代码,只是一个"管理者"。它的文件是 .sln,你双击它,VS 就能打开整套工程。
在工业项目里,一个解决方案通常对应一套系统。
比如你做一套注塑机监控系统,整个系统就是一个解决方案:InjectionMoldingSystem.sln。
项目(Project)是解决方案下的"功能单元"。
每个项目负责一块独立的功能,最终编译成一个独立的程序或组件(.exe 或 .dll)。
⚠️
.dll(动态链接库)是一种"功能包",不能直接运行,但可以被其他程序调用。
一套注塑机监控系统,可能包含这几个项目:
| 项目名称 | 职责 |
|---|---|
MoldingMonitor.UI | 操作界面(WPF) |
MoldingMonitor.Core | 业务逻辑、数据处理 |
MoldingMonitor.Comm | 设备通信(OPC UA等) |
MoldingMonitor.Tests | 单元测试 |
「每个项目各司其职,就像车间里的注塑班、质检班、维修班——分工明确,互不干扰。」
文件是项目里的最小单位,C# 代码文件以 .cs 结尾。
一个 .cs 文件通常对应一个类(Class)。类是代码的基本组织形式,后面章节会详细讲。
你现在只需要记住:一个功能 → 一个类 → 一个 .cs 文件,这是最清晰的组织方式。
除了 .cs 文件,项目里还可能有:
.xaml:WPF 界面描述文件(类似网页的 HTML)appsettings.json:配置文件(存 IP 地址、端口等参数)README.md:项目说明文档用一张树形图来感受一下:
InjectionMoldingSystem.sln ← 解决方案 │ ├── MoldingMonitor.UI ← 项目(界面层) │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ └── AlarmPanel.xaml.cs │ ├── MoldingMonitor.Core ← 项目(逻辑层) │ ├── DeviceDataModel.cs │ ├── AlarmService.cs │ └── ProductionCounter.cs │ └── MoldingMonitor.Comm ← 项目(通信层) ├── OpcUaClient.cs └── ModbusReader.cs
「看到这个结构,你就明白了:代码不是随便堆,而是按职责分层放置的。」
Step 1:打开上一节创建的解决方案,在 解决方案资源管理器 中,右键点击解决方案名称(最顶层那行)。
Step 2:选择 添加 > 新建项目,在弹出窗口中选择 类库(.NET 10),命名为 MoldingMonitor.Core,点击创建。

VS2026 Copilot 辅助:创建完成后,Copilot 会在右侧弹出建议面板,自动推荐适合"工业数据处理"场景的类模板,你可以一键接受或忽略。
Step 3:在新项目上右键 > 添加 > 新建项,选择 类(Class),命名为 ProductionCounter.cs,点击添加。
Step 4:回到原来的控制台项目,右键 > 添加 > 项目引用,勾选 MoldingMonitor.Core,点击确定。

这一步的作用是:让控制台项目能"调用"Core项目里的代码,就像让调度室能联系上车间一样。
Step 5:按 Ctrl + Shift + B 执行生成解决方案,确认两个项目都能编译通过(输出窗口显示"生成成功")。
如果你想用 VS2026 内置 Copilot 的 Vibe Coding 模式快速生成项目骨架,可以这样写 Prompt:
Prompt 示例: "在 .NET 10 类库项目中,创建一个名为 ProductionCounter 的类,包含:当前产量(整数)、目标产量(整数)、完成率(小数)三个属性,以及一个增加产量的方法,方法名用工业语义命名。"
Copilot 会直接生成带注释的类代码,你只需检查属性名是否符合你的业务命名规范即可。
这段代码演示了在两个项目之间调用类的完整流程——Core项目定义生产计数器,控制台项目调用它并输出结果。
csharp// ============================================================
// 文件位置:MoldingMonitor.Core / ProductionCounter.cs
// 职责:注塑机生产计数器,记录产量与目标完成情况
// ============================================================
namespace MoldingMonitor.Core
{
/// <summary>
/// 注塑机生产计数器
/// </summary>
public class ProductionCounter
{
// 当前已完成产量(单位:件)
public int CurrentCount { get; private set; }
// 目标产量(单位:件)
public int TargetCount { get; set; }
// 构造函数:初始化目标产量
public ProductionCounter(int targetCount)
{
TargetCount = targetCount;
CurrentCount = 0;
}
// 增加产量:每完成一件调用一次
public void IncrementProduction(int quantity = 1)
{
CurrentCount += quantity;
}
// 计算完成率(百分比)
public double GetCompletionRate()
{
if (TargetCount == 0) return 0;
return (double)CurrentCount / TargetCount * 100;
}
// 判断是否达成目标
public bool IsTargetReached()
{
return CurrentCount >= TargetCount;
}
}
}
csharp// ============================================================
// 文件位置:ConsoleApp1 / Program.cs(控制台项目)
// 职责:模拟注塑机生产过程,调用Core层计数器
// ============================================================
// 引用 Core 项目的命名空间(需先添加项目引用)
using MoldingMonitor.Core;
// 初始化生产计数器,今日目标:1000件
var productionCounter = new ProductionCounter(targetCount: 1000);
Console.WriteLine("=== 注塑机生产监控启动 ===");
Console.WriteLine($"今日目标产量:{productionCounter.TargetCount} 件");
// 模拟生产过程:分批次增加产量
int[] batchSizes = { 200, 350, 300, 180 };
foreach (var batchSize in batchSizes)
{
// 模拟每批次生产完成
productionCounter.IncrementProduction(batchSize);
Console.WriteLine($"批次完成 {batchSize} 件 → " +
$"累计:{productionCounter.CurrentCount} 件 | " +
$"完成率:{productionCounter.GetCompletionRate():F1}%");
}
// 输出最终结果
Console.WriteLine("========================");
if (productionCounter.IsTargetReached())
{
Console.WriteLine("✅ 今日目标达成!");
}
else
{
int remaining = productionCounter.TargetCount - productionCounter.CurrentCount;
Console.WriteLine($"⚠️ 距目标还差 {remaining} 件,请加快节拍。");
}

运行后,控制台会逐批次输出产量累计和完成率,最后根据是否达成目标输出不同提示。你可以修改 batchSizes 数组来模拟不同的生产节奏,感受数据流动的过程。
场景任务:汽车冲压车间需要一个简单的班次报告生成器,在控制台输出本班次的冲压产量、废品数量和良品率。
思路拆解:
StampingShiftReport.cs。csharp// 文件:MoldingMonitor.Core / StampingShiftReport.cs
namespace MoldingMonitor.Core
{
public class StampingShiftReport
{
public string ShiftName { get; set; } // 班次名称
public int TotalStampCount { get; set; } // 总冲压件数
public int DefectCount { get; set; } // 废品数量
// 计算良品率
public double GetYieldRate()
{
if (TotalStampCount == 0) return 0;
return (double)(TotalStampCount - DefectCount) / TotalStampCount * 100;
}
// 打印班次报告
public void PrintReport()
{
Console.WriteLine($"【{ShiftName}班次报告】");
Console.WriteLine($"总冲压量:{TotalStampCount} 件");
Console.WriteLine($"废品数量:{DefectCount} 件");
Console.WriteLine($"良品率:{GetYieldRate():F2}%");
}
}
}
// 文件:Program.cs(控制台项目调用)
using MoldingMonitor.Core;
var morningShift = new StampingShiftReport
{
ShiftName = "早",
TotalStampCount = 4800,
DefectCount = 36
};
morningShift.PrintReport();

运行后,控制台输出早班完整报告,良品率精确到小数点后两位——直接可以截图发给班长。
坑一:把所有代码都堆在一个项目里
❌ 错误做法:界面、通信、业务逻辑全写在 Program.cs 一个文件里
✅ 正确做法:按职责拆分项目,UI / Core / Comm 各一个
📌 原因:项目越大越难维护,拆分后改一处不影响其他模块,就像车间改造不用停整条产线。
坑二:新建项目时选错类型
❌ 错误做法:想做类库(.dll),却选了"控制台应用"
✅ 正确做法:类库选 类库(Class Library),可执行程序选 控制台应用 或 WPF应用
📌 原因:类库没有入口点,不能直接运行;选错类型,编译出来的东西根本用不了。
坑三:项目引用加了但命名空间没 using
❌ 错误做法:添加了项目引用,直接用类名,报"找不到类型"错误
✅ 正确做法:在文件顶部加 using MoldingMonitor.Core;
📌 原因:引用只是"打通了门",using 才是"告诉编译器去哪个房间找东西"。
「学完本节,你掌握了:」
解决方案是工程的"总包",项目是功能模块,文件是最小单元——三层结构,层层嵌套,各司其职。你知道了为什么不能把所有代码堆在一个地方,也学会了如何在 VS2026 中新增项目并建立项目间的引用关系。更重要的是,你开始用"分层思维"来组织代码,这是工业软件开发的基本功。
搞懂结构,才能盖出稳的楼。
📖 本文是《C# 工业数字化应用开发专家》系列第 008 节
上一节:【创建你的第一个 C# 控制台项目】
下一节:【变量与数据类型:int、double、string、bool】(明天更新)
💬 你在工作中有没有遇到过"文件放哪里"的困惑?
欢迎在评论区说说你的场景,也许下一篇案例就来自你的留言。
🔔 还没关注的同学记得点击关注,系列课程持续更新,学完这 420 节,从工厂小白到工业软件开发专家,我们一起走。
#C#编程入门 #工业数字化 #Visual Studio教程 #工厂工程师学编程 #dotNET开发
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!