延迟加载(Lazy Loading)是一种设计模式,它允许推迟对象的初始化,直到该对象真正被使用时才进行加载。这种技术可以帮助提高应用程序的性能和资源利用效率。
Lazy<T> 是.NET Framework 4.0引入的泛型类,提供了最简单的延迟加载实现。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppLazy
{
public class UserProfile
{
// 延迟加载的复杂对象
// ThreadSafetyMode.ExecutionAndPublication 确保线程安全
private Lazy<ExpensiveResource> _expensiveResource;
public UserProfile()
{
// 使用 LazyThreadSafetyMode 确保线程安全
_expensiveResource = new Lazy<ExpensiveResource>(
() => new ExpensiveResource(),
LazyThreadSafetyMode.ExecutionAndPublication
);
}
public ExpensiveResource GetResource()
{
// 只有在调用Value时才真正创建对象
return _expensiveResource.Value;
}
}
public class ExpensiveResource
{
public Guid ResourceId { get; } = Guid.NewGuid();
public ExpensiveResource()
{
// 模拟复杂的初始化过程
Console.WriteLine($"正在初始化复杂资源 {ResourceId}...");
Thread.Sleep(2000); // 模拟耗时操作
Console.WriteLine($"复杂资源 {ResourceId} 初始化完成。");
}
}
}
C#namespace AppLazy
{
internal class Program
{
static void Main(string[] args)
{
// 创建 UserProfile 实例
UserProfile userProfile = new UserProfile();
Console.WriteLine("创建 UserProfile 实例,但尚未初始化资源...");
// 第一次访问 ExpensiveResource
Console.WriteLine("第一次获取资源:");
ExpensiveResource resource1 = userProfile.GetResource();
// 再次访问,不会重复初始化
Console.WriteLine("第二次获取资源:");
ExpensiveResource resource2 = userProfile.GetResource();
// 验证是否是同一个实例
Console.WriteLine($"两次获取的资源是否是同一个实例:{object.ReferenceEquals(resource1, resource2)}");
}
}
}

在 Windows 系统开发中,有时我们需要获取文件、文件夹或特定文件类型的系统图标。本文将详细介绍几种在 C# 中提取系统图标的方法。
在开始之前,需要引入以下命名空间:
C#using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
C#using System.Runtime.InteropServices;
namespace AppGetIcon
{
public partial class Form1 : Form
{
private const uint SHGFI_ICON = 0x000000100;
private const uint SHGFI_SMALLICON = 0x000000000;
private const uint SHGFI_LARGEICON = 0x000000000;
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbSizeFileInfo,
uint uFlags
);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
public Form1()
{
InitializeComponent();
}
public Icon GetFileIcon(string filePath, bool isSmallIcon = true)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint flags = SHGFI_ICON | (isSmallIcon ? SHGFI_SMALLICON : SHGFI_LARGEICON);
IntPtr hImgSmall = SHGetFileInfo(
filePath,
0,
ref shinfo,
(uint)Marshal.SizeOf(shinfo),
flags
);
if (shinfo.hIcon == IntPtr.Zero)
return null;
return Icon.FromHandle(shinfo.hIcon);
}
private void btnGetIcon_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
string filePath = dialog.FileName;
Icon icon = GetFileIcon(filePath);
pictureBox1.Image = icon.ToBitmap();
}
}
}
}

在本教程中,我们将使用 Windows Forms 开发一个功能完整的截图应用程序。这个应用程序将支持以下核心功能:
在现代软件开发中,解耦是构建可维护、可扩展系统的关键。事件驱动架构(Event-Driven Architecture,简称 EDA)为我们提供了一种强大的解耦方案,允许组件之间通过事件进行松散耦合的通信。本文将深入探讨如何在 C# 中利用事件驱动架构实现应用解耦。
事件驱动架构基于以下关键概念:
我们将通过一个电子商务订单系统的例子,展示事件驱动架构的实际应用。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppEvent
{
public class Order
{
public string Id { get; set; }
public string CustomerId { get; set; }
public decimal TotalAmount { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
// 可以根据需要添加其他属性,例如订单状态、商品列表等
}
}
快捷键注册是一种在 Windows 应用程序中允许全局热键捕获的技术。通过正确注册快捷键,开发者可以让应用程序在任何情况下都能响应特定按键组合。
在 C# 中,我们主要使用 Windows API 中的以下方法来实现快捷键注册:
RegisterHotKey(): 注册全局热键UnregisterHotKey(): 取消注册热键WndProc(): 处理消息循环中的快捷键消息C#using System.Runtime.InteropServices;
namespace AppHotKey
{
public partial class Form1 : Form
{
// 定义快捷键消息常量
private const int WM_HOTKEY = 0x0312;
// 导入 Windows API 函数
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
// 快捷键修饰符枚举
[Flags]
public enum KeyModifiers
{
None = 0,
Alt = 1,
Ctrl = 2,
Shift = 4,
Windows = 8
}
// 快捷键 ID
private const int HOTKEY_ID = 1;
public Form1()
{
InitializeComponent();
// 注册快捷键:Ctrl + Shift + A
RegisterHotKey(
this.Handle,
HOTKEY_ID,
(uint)(KeyModifiers.Ctrl | KeyModifiers.Shift),
(uint)Keys.A
);
}
// 重写消息处理方法
protected override void WndProc(ref Message m)
{
// 检查是否为快捷键消息
if (m.Msg == WM_HOTKEY)
{
// 获取快捷键 ID
int id = m.WParam.ToInt32();
if (id == HOTKEY_ID)
{
// 快捷键触发时的处理逻辑
HandleHotkeyTriggered();
}
}
base.WndProc(ref m);
}
// 快捷键触发处理方法
private void HandleHotkeyTriggered()
{
MessageBox.Show("快捷键 Ctrl + Shift + A 被按下!");
// 在这里添加您想要执行的具体操作
}
// 程序关闭时取消注册快捷键
protected override void OnFormClosing(FormClosingEventArgs e)
{
UnregisterHotKey(this.Handle, HOTKEY_ID);
base.OnFormClosing(e);
}
}
}
