最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#上位機(jī)通過Http傳輸文件的操作指南(壓縮文件,圖片,csv等等)

 更新時(shí)間:2026年06月23日 09:04:20   作者:_Csharp  
C# Win上位機(jī)HTTP文件上傳流程,涵蓋單文件、多文件批量、壓縮包上傳,支持進(jìn)度回調(diào)、參數(shù)附帶、異常處理,服務(wù)端ASP.NETCoreWebAPI接收文件流,兼容WinForm/WPF,位機(jī),適配大文件上傳,優(yōu)化高頻業(yè)務(wù)場(chǎng)景,確保高效穩(wěn)定

C# WinForm/WPF 上位機(jī) HTTP 文件上傳流程

覆蓋場(chǎng)景:?jiǎn)挝募蟼鳎–SV / 圖片 / 壓縮包)、多文件批量上傳、多文件先壓縮 ZIP 再上傳、后端接收保存 + 解析文件,分客戶端(C# 上位機(jī))服務(wù)端(ASP.NET Core API) 兩大部分,兼容 WinForm/WPF,支持大文件、進(jìn)度回調(diào)、參數(shù)附帶、異常處理。

一、整體技術(shù)選型

  1. 客戶端:HttpClient(推薦,線程安全,替代 WebClient),System.IO.Compression 實(shí)現(xiàn)本地多文件打包 ZIP
  2. 服務(wù)端:ASP.NET Core WebAPI,接收 IFormFile 文件流
  3. 支持文件類型:.csv/.jpg/.png/.bmp/.gif/.zip/.rar/.txt/.xlsx 等任意二進(jìn)制文件
  4. 功能點(diǎn):
    • 單文件直接 HTTP 上傳
    • 多選文件批量并行上傳
    • 本地打包多文件為臨時(shí) ZIP,僅上傳一個(gè)壓縮包(減少請(qǐng)求次數(shù))
    • 上傳進(jìn)度實(shí)時(shí)回調(diào)(UI 進(jìn)度條)
    • 攜帶自定義業(yè)務(wù)參數(shù)(設(shè)備編號(hào)、時(shí)間戳、工位號(hào))
    • 后端文件校驗(yàn)、自動(dòng)創(chuàng)建目錄、重命名防覆蓋、解壓服務(wù)端 ZIP
    • 超時(shí)、斷流、文件不存在、超大文件異常捕獲

第一部分:C# 上位機(jī)客戶端通用工具類(WinForm/WPF 通用)

新建工具類 HttpFileUploadHelper.cs,無需第三方 NuGet,純.NET 原生。

1. 基礎(chǔ)依賴引用

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.IO.Compression;

2. 進(jìn)度回調(diào)委托(UI 更新進(jìn)度條)

/// <summary>上傳進(jìn)度回調(diào):當(dāng)前字節(jié)、總字節(jié)</summary>
public delegate void UploadProgressDelegate(long currentBytes, long totalBytes);
public static class HttpFileUploadHelper
{
    // 全局HttpClient靜態(tài)實(shí)例,復(fù)用連接(禁止每次new HttpClient)
    private static readonly HttpClient _httpClient = new HttpClient()
    {
        Timeout = TimeSpan.FromMinutes(5) // 大文件5分鐘超時(shí)
    };
    #region 場(chǎng)景1:?jiǎn)挝募苯由蟼鳎–SV/圖片/壓縮包通用)
    /// <summary>
    /// 單文件HTTP上傳
    /// </summary>
    /// <param name="apiUrl">后端上傳接口地址</param>
    /// <param name="filePath">本地文件完整路徑</param>
    /// <param name="businessParams">自定義業(yè)務(wù)參數(shù) 如設(shè)備Id、工位</param>
    /// <param name="progress">上傳進(jìn)度回調(diào)</param>
    /// <param name="cancellationToken">取消上傳</param>
    /// <returns>后端返回的JSON字符串</returns>
    public static async Task<string> UploadSingleFileAsync(
        string apiUrl,
        string filePath,
        Dictionary<string, string> businessParams = null,
        UploadProgressDelegate progress = null,
        CancellationToken cancellationToken = default)
    {
        if (!File.Exists(filePath))
            throw new FileNotFoundException("文件不存在", filePath);
        var fileInfo = new FileInfo(filePath);
        long totalLength = fileInfo.Length;
        // 構(gòu)造multipart/form-data表單
        using var content = new MultipartFormDataContent();
        // 1. 添加業(yè)務(wù)自定義參數(shù)
        if (businessParams != null)
        {
            foreach (var kv in businessParams)
            {
                content.Add(new StringContent(kv.Value), kv.Key);
            }
        }
        // 2. 創(chuàng)建帶進(jìn)度監(jiān)聽的文件流
        using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true);
        var progressStream = new ProgressStream(fileStream, progress, totalLength);
        var streamContent = new StreamContent(progressStream);
        // 設(shè)置文件MIME類型
        string mimeType = GetMimeType(fileInfo.Extension);
        streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(mimeType);
        content.Add(streamContent, "uploadFile", fileInfo.Name);
        // 3. 發(fā)起POST請(qǐng)求
        using var response = await _httpClient.PostAsync(apiUrl, content, cancellationToken);
        response.EnsureSuccessStatusCode(); // 非200直接拋異常
        return await response.Content.ReadAsStringAsync(cancellationToken);
    }
    #endregion
    #region 場(chǎng)景2:多文件分別批量上傳(多次HTTP請(qǐng)求)
    /// <summary>批量逐個(gè)上傳多個(gè)獨(dú)立文件</summary>
    public static async Task<List<string>> UploadMultiFilesSeparateAsync(
        string apiUrl,
        List<string> filePaths,
        Dictionary<string, string> businessParams = null,
        UploadProgressDelegate singleFileProgress = null,
        CancellationToken cancellationToken = default)
    {
        var resultList = new List<string>();
        foreach (var file in filePaths)
        {
            var res = await UploadSingleFileAsync(apiUrl, file, businessParams, singleFileProgress, cancellationToken);
            resultList.Add(res);
        }
        return resultList;
    }
    #endregion
    #region 場(chǎng)景3:多文件本地打包ZIP后只上傳一個(gè)壓縮包(推薦大量文件場(chǎng)景)
    /// <summary>
    /// 多個(gè)文件先壓縮成臨時(shí)ZIP,再上傳壓縮包,上傳完成自動(dòng)刪除臨時(shí)zip
    /// </summary>
    public static async Task<string> UploadFilesAsZipAsync(
        string apiUrl,
        List<string> sourceFilePaths,
        string tempZipSavePath = null,
        Dictionary<string, string> businessParams = null,
        UploadProgressDelegate progress = null,
        CancellationToken cancellationToken = default)
    {
        // 生成臨時(shí)壓縮包路徑(不傳則自動(dòng)放系統(tǒng)臨時(shí)目錄)
        if (string.IsNullOrEmpty(tempZipSavePath))
        {
            tempZipSavePath = Path.Combine(Path.GetTempPath(), $"upload_{Guid.NewGuid():N}.zip");
        }
        // 本地打包所有文件到zip
        CreateZipFromFiles(sourceFilePaths, tempZipSavePath);
        try
        {
            // 上傳生成的zip壓縮包
            var result = await UploadSingleFileAsync(apiUrl, tempZipSavePath, businessParams, progress, cancellationToken);
            return result;
        }
        finally
        {
            // 上傳成功/失敗都刪除臨時(shí)壓縮文件
            if (File.Exists(tempZipSavePath))
                File.Delete(tempZipSavePath);
        }
    }
    /// <summary>將多個(gè)本地文件打包成ZIP</summary>
    private static void CreateZipFromFiles(List<string> fileList, string zipPath)
    {
        if (File.Exists(zipPath)) File.Delete(zipPath);
        using var zipFile = ZipFile.Open(zipPath, ZipArchiveMode.Create);
        foreach (var file in fileList)
        {
            if (!File.Exists(file)) continue;
            var fileName = Path.GetFileName(file);
            zipFile.CreateEntryFromFile(file, fileName, CompressionLevel.Optimal);
        }
    }
    #endregion
    #region 輔助工具:MIME類型映射 + 進(jìn)度監(jiān)聽流
    /// <summary>文件后綴對(duì)應(yīng)MIME類型</summary>
    private static string GetMimeType(string ext)
    {
        return ext.ToLower() switch
        {
            ".csv" => "text/csv",
            ".jpg" or ".jpeg" => "image/jpeg",
            ".png" => "image/png",
            ".bmp" => "image/bmp",
            ".gif" => "image/gif",
            ".zip" => "application/zip",
            ".rar" => "application/x-rar-compressed",
            ".txt" => "text/plain",
            ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            _ => "application/octet-stream" // 未知二進(jìn)制文件通用
        };
    }
    /// <summary>包裝文件流,讀取時(shí)觸發(fā)上傳進(jìn)度回調(diào)</summary>
    private class ProgressStream : Stream
    {
        private readonly Stream _innerStream;
        private readonly UploadProgressDelegate _progressCallback;
        private readonly long _totalLength;
        private long _readBytes;
        public ProgressStream(Stream inner, UploadProgressDelegate callback, long totalLen)
        {
            _innerStream = inner;
            _progressCallback = callback;
            _totalLength = totalLen;
            _readBytes = 0;
        }
        public override int Read(byte[] buffer, int offset, int count)
        {
            var read = _innerStream.Read(buffer, offset, count);
            if (read > 0)
            {
                _readBytes += read;
                _progressCallback?.Invoke(_readBytes, _totalLength);
            }
            return read;
        }
        // 下面簡(jiǎn)單轉(zhuǎn)發(fā)所有Stream虛方法
        public override bool CanRead => _innerStream.CanRead;
        public override bool CanSeek => _innerStream.CanSeek;
        public override bool CanWrite => _innerStream.CanWrite;
        public override long Length => _innerStream.Length;
        public override long Position { get; set; }
        public override void Flush() => _innerStream.Flush();
        public override long Seek(long offset, SeekOrigin origin) => _innerStream.Seek(offset, origin);
        public override void SetLength(long value) => _innerStream.SetLength(value);
        public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count);
        protected override void Dispose(bool disposing) => _innerStream.Dispose();
    }
    #endregion
}

3. WinForm 上位機(jī)界面調(diào)用示例(帶進(jìn)度條)

界面控件:

  • textBox_ApiUrl:輸入后端接口地址 http://localhost:5000/api/FileUpload/Upload
  • progressBar1:上傳進(jìn)度條
  • label_ProgressText:顯示百分比
  • button_SelectSingle:選擇單個(gè)文件上傳
  • button_SelectMultiZip:多選文件打包 ZIP 上傳
using System.Windows.Forms;
private async void button_SelectSingle_Click(object sender, EventArgs e)
{
    using var dialog = new OpenFileDialog
    {
        Filter = "所有文件|*.*|CSV文件|*.csv|圖片|*.jpg;*.png;*.bmp|壓縮包|*.zip;*.rar",
        Multiselect = false
    };
    if (dialog.ShowDialog() != DialogResult.OK) return;
    string filePath = dialog.FileName;
    string api = textBox_ApiUrl.Text.Trim();
    // 業(yè)務(wù)參數(shù):上位機(jī)設(shè)備信息
    var param = new Dictionary<string, string>()
    {
        {"DeviceId", "MACHINE_001"},
        {"Station", "裝配工位3"},
        {"UploadTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
    };
    // 進(jìn)度回調(diào)(UI線程安全,Invoke更新控件)
    void ProgressUpdate(long curr, long total)
    {
        double percent = curr * 100.0 / total;
        this.Invoke(new Action(() =>
        {
            progressBar1.Maximum = (int)total / 1024; // KB單位
            progressBar1.Value = (int)curr / 1024;
            label_ProgressText.Text = $"已上傳 {curr / 1024}KB / {total / 1024}KB  {percent:F1}%";
        }));
    }
    try
    {
        string result = await HttpFileUploadHelper.UploadSingleFileAsync(api, filePath, param, ProgressUpdate);
        MessageBox.Show($"上傳成功!服務(wù)端返回:\n{result}");
    }
    catch (Exception ex)
    {
        MessageBox.Show($"上傳失敗:{ex.Message}");
    }
}
// 多選文件打包ZIP上傳
private async void button_SelectMultiZip_Click(object sender, EventArgs e)
{
    using var dialog = new OpenFileDialog
    {
        Multiselect = true,
        Filter = "所有文件|*.*"
    };
    if (dialog.ShowDialog() != DialogResult.OK) return;
    List<string> files = dialog.FileNames.ToList();
    string api = textBox_ApiUrl.Text.Trim();
    var param = new Dictionary<string, string>() { {"DeviceId", "MACHINE_001"} };
    void ProgressUpdate(long curr, long total)
    {
        double percent = curr * 100.0 / total;
        this.Invoke(new Action(() =>
        {
            progressBar1.Maximum = (int)total / 1024;
            progressBar1.Value = (int)curr / 1024;
            label_ProgressText.Text = $"壓縮包上傳進(jìn)度 {percent:F1}%";
        }));
    }
    try
    {
        string res = await HttpFileUploadHelper.UploadFilesAsZipAsync(api, files, null, param, ProgressUpdate);
        MessageBox.Show($"打包上傳完成:{res}");
    }
    catch (Exception ex)
    {
        MessageBox.Show($"打包上傳異常:{ex.Message}");
    }
}

4. WPF 適配說明

WPF 無需修改工具類,進(jìn)度更新把 this.Invoke 替換成 Application.Current.Dispatcher.Invoke 即可。

第二部分:后端ASP.NETCore API 接收文件處理(配套上位機(jī))

1. 創(chuàng)建 FileUpload 控制器FileUploadController.cs

支持:接收單文件、接收壓縮包并自動(dòng)解壓、讀取業(yè)務(wù)參數(shù)、文件存儲(chǔ)、返回 JSON 結(jié)果

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.IO;
using System.IO.Compression;
namespace UploadServer.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class FileUploadController : ControllerBase
    {
        // 文件根存儲(chǔ)目錄
        private readonly string _saveRoot = Path.Combine(AppContext.BaseDirectory, "UploadFiles");
        public FileUploadController()
        {
            // 不存在自動(dòng)創(chuàng)建目錄
            if (!Directory.Exists(_saveRoot))
                Directory.CreateDirectory(_saveRoot);
        }
        /// <summary>統(tǒng)一上傳接口:接收單文件/zip壓縮包</summary>
        [HttpPost("Upload")]
        public IActionResult Upload([FromForm] UploadModel model)
        {
            // 1. 獲取上位機(jī)傳的業(yè)務(wù)參數(shù)
            string deviceId = model.DeviceId ?? "UnknownDevice";
            string station = model.Station ?? "Default";
            string uploadTime = model.UploadTime ?? DateTime.Now.ToString("yyyyMMddHHmmss");
            if (model.uploadFile == null || model.uploadFile.Length == 0)
                return BadRequest(new { code = -1, msg = "未檢測(cè)到上傳文件" });
            // 按設(shè)備+日期分目錄存儲(chǔ)
            string dateDir = DateTime.Now.ToString("yyyy-MM-dd");
            string targetDir = Path.Combine(_saveRoot, deviceId, dateDir);
            Directory.CreateDirectory(targetDir);
            // 原始文件名,重命名防止覆蓋
            string fileName = Path.GetFileName(model.uploadFile.FileName);
            string saveFullPath = Path.Combine(targetDir, $"{uploadTime}_{fileName}");
            // 保存文件到磁盤
            using var stream = new FileStream(saveFullPath, FileMode.Create);
            model.uploadFile.CopyTo(stream);
            // 2. 如果是zip壓縮包,自動(dòng)解壓到同目錄unzip文件夾
            if (Path.GetExtension(fileName).ToLower() == ".zip")
            {
                string unzipDir = Path.Combine(targetDir, $"unzip_{Path.GetFileNameWithoutExtension(fileName)}");
                Directory.CreateDirectory(unzipDir);
                ZipFile.ExtractToDirectory(saveFullPath, unzipDir, true); // true覆蓋重名
            }
            // 3. 返回成功JSON給上位機(jī)
            return Ok(new
            {
                code = 0,
                msg = "文件接收處理完成",
                data = new
                {
                    DeviceId = deviceId,
                    SavePath = saveFullPath,
                    FileSize = model.uploadFile.Length,
                    IsZip = Path.GetExtension(fileName).ToLower() == ".zip",
                    UnzipFolder = Path.GetDirectoryName(saveFullPath) + $"/unzip_{Path.GetFileNameWithoutExtension(fileName)}"
                }
            });
        }
    }
    /// <summary>接收表單參數(shù)綁定模型</summary>
    public class UploadModel
    {
        public IFormFile uploadFile { get; set; }
        // 上位機(jī)自定義業(yè)務(wù)參數(shù)
        public string DeviceId { get; set; }
        public string Station { get; set; }
        public string UploadTime { get; set; }
    }
}

2. 后端配置文件大小限制(Program.cs)

默認(rèn)ASP.NET限制文件 30MB,上位機(jī)上傳大圖片 / 大 CSV / 大壓縮包需要放開限制:

var builder = WebApplication.CreateBuilder(args);

// 放開文件上傳最大尺寸 100MB
builder.Services.Configure<FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = 100 * 1024 * 1024;
});

builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run("http://localhost:5000");

第三部分:上位機(jī)高頻業(yè)務(wù)場(chǎng)景總結(jié)與優(yōu)化方案

場(chǎng)景 1:?jiǎn)?CSV / 單圖片實(shí)時(shí)上傳(巡檢截圖、報(bào)表)

直接調(diào)用 UploadSingleFileAsync,無需壓縮,上傳速度最快,適合單次少量文件。

場(chǎng)景 2:?jiǎn)未螏资习購(gòu)垐D片 + 報(bào)表 CSV 批量上傳

優(yōu)先用本地打包 ZIP 上傳 UploadFilesAsZipAsync 優(yōu)勢(shì):

  1. 只發(fā)起 1 次 HTTP 請(qǐng)求,減少網(wǎng)絡(luò)握手耗時(shí)
  2. 壓縮后體積大幅減?。▓D片無損壓縮、文本 CSV 壓縮率極高)
  3. 后端自動(dòng)解壓,一次性拿到全部原始文件
  4. 自動(dòng)清理本地臨時(shí)壓縮包,無垃圾文件殘留

場(chǎng)景 3:定時(shí)循環(huán)采集文件,后臺(tái)靜默上傳

封裝異步后臺(tái)任務(wù),搭配 CancellationTokenSource 支持停止上傳,UI 不卡死。

場(chǎng)景 4:超大文件(>500MB)斷點(diǎn)續(xù)傳擴(kuò)展

現(xiàn)有代碼是完整文件上傳,超大文件建議分片上傳:

  1. 上位機(jī)分割文件為 10MB 分片,攜帶分片索引、文件 MD5
  2. 后端接收分片緩存,全部接收完成合并完整文件
  3. 工具類可在現(xiàn)有基礎(chǔ)上增加分片上傳方法

第四部分:常見問題踩坑指南

  • HttpClient 頻繁創(chuàng)建導(dǎo)致套接字泄漏 解決方案:工具類靜態(tài)全局復(fù)用 HttpClient,不要按鈕點(diǎn)擊每次 new。
  • WinForm 跨線程更新進(jìn)度條報(bào)錯(cuò) 必須使用 Invoke/BeginInvoke 切 UI 主線程更新控件。
  • 后端接收文件為空 IFormFile = null
    • 前端表單字段名必須和后端 uploadFile 完全一致(區(qū)分大小寫)
    • 接口必須標(biāo)記 [FromForm],不能用 JSON 傳文件
    • 檢查 Content-Type 為 multipart/form-data
  • 文件上傳超時(shí)
    • 增大 HttpClient.Timeout
    • 后端放開 MultipartBodyLengthLimit 限制
    • 大文件優(yōu)先壓縮再上傳
  • 中文文件名亂碼 ASP.NET Core 默認(rèn)支持,無需額外配置;舊版 IIS 部署需修改 web.config 編碼 UTF-8。
  • 臨時(shí) ZIP 文件殘留 工具類 finally 塊自動(dòng)刪除,即使上傳報(bào)錯(cuò)也會(huì)清理。

第五部分:擴(kuò)展功能建議(工業(yè)上位機(jī)常用)

  1. 上傳前計(jì)算文件 MD5,傳給后端做文件完整性校驗(yàn)
  2. 增加上傳失敗自動(dòng)重試機(jī)制(網(wǎng)絡(luò)波動(dòng))
  3. 上傳隊(duì)列管理,避免多線程并發(fā)上傳占用帶寬
  4. 增加日志寫入本地:上傳成功 / 失敗記錄文件、時(shí)間、設(shè)備號(hào)
  5. HTTPS 加密傳輸(生產(chǎn)環(huán)境禁止 HTTP 明文)
  6. 接口增加 Token 身份校驗(yàn),防止非法設(shè)備上傳文件

到此這篇關(guān)于C#上位機(jī)通過Http傳輸文件(壓縮文件,圖片,csv等等)的文章就介紹到這了,更多相關(guān)C# Http傳輸文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#解決文件被占用資源,無法刪除或修改的方法

    C#解決文件被占用資源,無法刪除或修改的方法

    這篇文章主要介紹C#解決文件被占用資源,比較實(shí)用,需要的朋友可以參考下。
    2016-06-06
  • C#中GraphicsPath的Flatten方法用法實(shí)例

    C#中GraphicsPath的Flatten方法用法實(shí)例

    這篇文章主要介紹了C#中GraphicsPath的Flatten方法,實(shí)例分析了Flatten方法的相關(guān)使用技巧,需要的朋友可以參考下
    2015-06-06
  • C# WinForms中實(shí)現(xiàn)MD5的加密

    C# WinForms中實(shí)現(xiàn)MD5的加密

    MD5(消息摘要算法第5版)是一種廣泛使用的哈希函數(shù),可以生成一個(gè)128位(16字節(jié))的哈希值,通常用于數(shù)據(jù)完整性校驗(yàn)和密碼存儲(chǔ),在Windows Forms應(yīng)用程序中實(shí)現(xiàn)MD5加密,可以用于用戶密碼的安全存儲(chǔ)和數(shù)據(jù)的完整性驗(yàn)證,本文將詳細(xì)介紹了如何在WinForms中實(shí)現(xiàn)MD5加密
    2024-10-10
  • C#中Region、Exclude的用法小結(jié)

    C#中Region、Exclude的用法小結(jié)

    本文主要介紹了C#中Region、Exclude的用法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • SuperSocket入門--Telnet服務(wù)器和客戶端請(qǐng)求處理

    SuperSocket入門--Telnet服務(wù)器和客戶端請(qǐng)求處理

    本文的控制臺(tái)項(xiàng)目是根據(jù)SuperSocket官方Telnet示例代碼進(jìn)行調(diào)試的,官方示例代碼:Telnet示例。下面跟著小編一起來看下吧
    2017-01-01
  • C# 大數(shù)據(jù)導(dǎo)出word的假死報(bào)錯(cuò)的處理方法

    C# 大數(shù)據(jù)導(dǎo)出word的假死報(bào)錯(cuò)的處理方法

    C# 大數(shù)據(jù)導(dǎo)出word的假死報(bào)錯(cuò)的處理方法,需要的朋友可以參考一下
    2013-03-03
  • C#實(shí)現(xiàn)六大設(shè)計(jì)原則之接口隔離原則

    C#實(shí)現(xiàn)六大設(shè)計(jì)原則之接口隔離原則

    這篇文章介紹了C#實(shí)現(xiàn)六大設(shè)計(jì)原則之接口隔離原則的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • C#中抽象方法與虛擬方法的區(qū)別

    C#中抽象方法與虛擬方法的區(qū)別

    這篇文章主要介紹了C#中抽象方法與虛擬方法的區(qū)別,對(duì)于C#初學(xué)者來說可以深入理解抽象方法與虛擬方法,需要的朋友可以參考下
    2014-08-08
  • C#操作Word中水印添加和移除的完整指南

    C#操作Word中水印添加和移除的完整指南

    在軟件系統(tǒng)開發(fā)過程中,文檔處理功能往往是企業(yè)級(jí)應(yīng)用的重要組成部分,本文將詳細(xì)介紹如何利用?Spire.Doc?for?.NET?組件,通過?C#?代碼實(shí)現(xiàn)?Word?文檔中文本水印的添加、圖片水印的添加以及已有水印的移除操作,有需要的小伙伴可以了解下
    2026-05-05
  • C#?引用類型參數(shù)ref詳解

    C#?引用類型參數(shù)ref詳解

    C#中ref和out關(guān)鍵字允許按引用傳遞參數(shù),以修改實(shí)參的值,本文給大家介紹C#引用類型參數(shù)ref的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2025-06-06

最新評(píng)論

郯城县| 大姚县| 五指山市| 驻马店市| 手游| 祥云县| 玛纳斯县| 曲靖市| 武邑县| 岳普湖县| 定襄县| 奇台县| 兴安盟| 诏安县| 平谷区| 临海市| 郁南县| 碌曲县| 奉贤区| 郑州市| 丹寨县| 南阳市| 凭祥市| 宜城市| 合江县| 内丘县| 商洛市| 义马市| 新乡县| 柘荣县| 贵溪市| 克拉玛依市| 子洲县| 德令哈市| 长沙市| 十堰市| 美姑县| 库车县| 辽阳市| 巫山县| 积石山|