csharp
文章平均质量分 88
walter lv
这个作者很懒,什么都没留下…
展开
-
在制作多框架项目的 NuGet 包时应该注意的问题(buildMultiTargeting TargetFrameworks)
制作一个 dll 引用的 NuGet 包简直是一键完成,无论是不是多框架项目;制作 dotnet-tools 也是如此。但如果需要自定义一些编译步骤,那么就需要在制作 NuGet 包时做很多的特殊处理了。本文介绍制作适用于多框架项目的 NuGet 工具包时应该注意的问题。本文内容背景知识NuGet 包内的文件夹结构制作有自定义功能的 NuGet 包执行时机1. 仅含 `build` 文件夹的 NuGet 包装到单框架项目中2. 仅含 `build` 文件夹的 NuGet 包装到多框架项目中3. 包含原创 2020-06-30 10:03:02 · 2952 阅读 · 0 评论 -
Unity3D 入门:最简单的控制视角,以及控制角色前进、转向的脚本
本文依然是 Unity3D 的入门篇。作为 Unity3D 的入门读者,你可能希望迅速让你能在游戏中操作你的视角,或者让角色移动。本文内容创建脚本最简代码创建脚本作为入门篇,可能需要讲一下如何创建脚本。按下图,在 Unity 编辑器中:在 Hierarchy(层级)中选中主摄像机;在 Inspector(检查器)中选择最后那个 Add Component(添加组件);选择 New Script(新建脚本)输入脚本名称,然后点击 Create and Add(创建并添加)。接下来,我们原创 2020-06-30 09:54:44 · 6883 阅读 · 0 评论 -
Unity3D 入门:使用 Visual Studio 开发 Unity C# 脚本,说说根目录的那些 sln 和 csproj 文件
本文介绍 Unity3D 项目根目录的 sln 和 csproj 文件,你将知道如何正确理解和使用它们。对于传统 .NET/C# 的开发者来说,在解决方案中管理 NuGet 包,在 C# 项目中引用 dll 或 NuGet 包是家常便饭。但在 Unity 项目里面,你可能要改变这一观念——因为 Unity 项目里面实际上并不存在 sln 和 csproj 文件。等等!那我们在根目录看到的那些 sln 和 csproj 文件是什么?那只是 Unity 编辑器为了让你方便写 C# 代码临时生成给你用的原创 2020-06-30 09:53:27 · 4394 阅读 · 1 评论 -
三种方法为 ASP.NET Core 对外服务添加 https 支持(kestrel / frp / nginx)
虽然使用 Visual Studio 创建 ASP.NET Core 程序的时候可以选择是否添加 https 支持,不过这种方式只添加了 localhost 的证书,只有本地访问时浏览器才会承认。真正对外公开服务的时候这样是绝对没法儿提供 https 服务的。本文介绍使用三种不同的方式添加 https 的支持,三种方法各有优劣,本文会进行比较并给出不同的适用场景。你自己选择就好。本文内容你需...原创 2020-04-30 11:52:10 · 1728 阅读 · 0 评论 -
使用 Kestrel 为你的 ASP.NET Core 服务添加 https 支持
Kestrel 是一个跨平台的适用于 ASP.NET Core 的 Web 服务器。它内置集成在了 ASP.NET Core 项目模板中,所以编写和对外开放一个 Web 服务会非常简单。虽然不推荐直接使用 Kestrel 对外提供 Web 服务,但为了简单的话,临时使用也是非常不错的选择。Kestrel 是一个跨平台的适用于 ASP.NET Core 的 Web 服务器。Kestrel 只...原创 2020-04-30 11:51:29 · 1748 阅读 · 0 评论 -
Win32 方法 CreateFile 中选择合适的文件打开模式(CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXI
Windows 打开文件的 API 中提供了多种不同的文件打开方式。你可以根据你的业务场景选择适合你的文件打开方式。本文内容Windows API`dwCreationDisposition``CREATE_NEW``CREATE_ALWAYS``OPEN_EXISTING``OPEN_ALWAYS``TRUNCATE_EXISTING`Windows APIOpenFile 方法只能打开...原创 2020-04-30 11:50:29 · 2539 阅读 · 0 评论 -
.NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
.NET 中文件打开的 API File.Open 提供了多种不同的文件打开方式,这些方式大多数与 Windows 文件 API 中的模式是对应的,但也有一些 .NET 层面的判断以及名称的变化。在 .NET 层你可以选择适合你业务场景需要的文件打开方式。本文内容文件打开方式`FileMode``CreateNew``Create``Open``OpenOrCreate``Truncate``...原创 2020-04-30 11:49:27 · 1083 阅读 · 1 评论 -
WPF 中如何创建忽略 DPI 属性的图片
WPF 框架设计为与 DPI 无关,但你依然可能遇到 DPI 问题。尤其是 Image 控件显示的图片会根据图片 EXIF 中的 DPI 信息和屏幕 DPI 自动缩放图片。对于 UI 用图来说这是好事,但对于软件用户随便插入的图片来说就不是了——用户传入的图片可能是各种各样不统一的 DPI。因此这种 DPI 我们应该忽略。本文内容解决方法`DrawingImage`解决方法直接设置 Ima...原创 2020-04-30 11:48:31 · 481 阅读 · 0 评论 -
为什么不应该公开用来同步的加锁对象?为什么不应该 lock(this)/lock(string) 或者 lock 任何非私有对象?
如果你编写线程安全代码时为了省事儿直接 lock(this),或者早已听说不应该 lock(this),只是不知道原因,那么阅读本文可以帮助你了解原因。本文内容原因实例扩展lock 公开的属性lock 字符串lock 其他任何可能被其他对象获取的公开对象结论原因不应该 lock(this) 是因为你永远不知道别人会如何使用你的对象,永远不知道别人会在哪里加锁。于是稍不注意就可能死锁!实例...原创 2020-04-30 11:47:27 · 452 阅读 · 0 评论 -
为什么实现 .NET 的 ICollection 集合时需要实现 SyncRoot 属性?如何正确实现这个属性?
非泛型版本的 ICollection 中有 IsSynchronized 属性和 SyncRoot 属性,这两个属性被用来设计成以线程安全的方式访问和修改集合。不过这个设计让线程安全的访问由集合的实现方转嫁到了调用方,导致要么很难实现,要么很难调用。虽然泛型版本的 ICollection<T> 已经改进了设计,不再引入 SyncRoot 这样的属性到接口中,但如果我们在某些场景下需要...原创 2020-04-30 11:46:40 · 767 阅读 · 0 评论 -
.NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
在解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。。其原因是所解压的文件并非 zip 文件。本文内容异常原因异常在解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。 在 System.IO.Compression.ZipArchive.Read...原创 2020-04-30 11:45:48 · 10097 阅读 · 0 评论 -
如何在旧版本的 .NET Core / Framework 中使用 C# 8 的异步流(IAsyncDisposable / IAsyncEnumerable / IAsyncEnumerator)
C# 8.0 为我们带来了异步流,可以使用 async foreach,不过使用此语法需要 IAsyncEnumerable / IAsyncEnumerator 类型。本文介绍如何在旧版本的 .NET Framework 和旧版本的 .NET Core 中获得此类型。本文内容异步流所需版本安装 Microsoft.Bcl.AsyncInterfaces使用异步流定义支持异步流的方法使用 aw...原创 2020-04-30 11:44:56 · 1061 阅读 · 0 评论 -
.NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
林德熙 小伙伴希望保存一个文件,并且希望如果出错了也要不断地重试。然而我认为如果一直错误则应该对外抛出异常让调用者知道为什么会一直错误。这似乎是一个矛盾的要求。然而最终我想到了一个办法:让重试一直进行下去,谁需要关心异常谁就去 catch 异常,不需要关心异常的模块则跟着一直重试直到成功。我们通过编写一个自己的 Awaiter 来实现,本文将说明其思路和最终实现的代码。本文内容Awaite...原创 2020-03-31 07:57:50 · 493 阅读 · 1 评论 -
了解 .NET/C# 程序集的加载时机,以便优化程序启动性能
林德熙在 C# 程序集数量对软件启动性能的影响 一文中说到程序集数量对程序启动性能的影响。在那篇文章中,我们得出结论,想同类数量的情况下,程序集的数量越多,程序启动越慢。额外的,不同的代码编写方式对程序集的加载性能也有影响。本文将介绍 .NET 中程序集的加载时机,了解这个时机能够对启动期间程序集的加载性能带来帮助。本文内容程序集加载方式对性能的影响程序集的加载时机程序集加载方式对性能的影...原创 2020-03-31 07:50:13 · 706 阅读 · 0 评论 -
在 Visual Studio 中使用 EditorConfig 统一代码风格(含原生与插件)
EditorConfig 是一种被各种编辑器广泛支持的配置,使用此配置有助于项目在整个团队中保持一致的代码风格。Visual Studio 2017 开始原生支持 EditorConfig。本文将介绍 Visual Studio 对 EditorConfig 的支持情况(含原生与插件),并给出符合 .NET 和 C# 约定的 EditorConfig 详细设置。本文内容EditorConfi...原创 2020-03-31 07:46:39 · 2953 阅读 · 0 评论 -
使用并解析 OPML 格式的订阅列表来转移自己的 RSS 订阅(概念篇)
OPML 全称是 Outline Processor Markup Language ,即 大纲处理标记语言。目前流行于收集博客的 RSS 源,便于用户转移自己的订阅项目。本文将介绍这个古老的格式,并提供一个 .NET 上的简易解析器。本文分为两个部分,一个是理解 OPML 格式,一个是解析此格式:概念篇(本文)解析篇本文内容OPML 格式典型的 OPML 文件OPML 文件中的节...原创 2020-02-29 14:23:03 · 3169 阅读 · 0 评论 -
使用并解析 OPML 格式的订阅列表来转移自己的 RSS 订阅(解析篇)
OPML 全称是 Outline Processor Markup Language ,即 大纲处理标记语言。目前流行于收集博客的 RSS 源,便于用户转移自己的订阅项目。本文将介绍这个古老的格式,并提供一个 .NET 上的简易解析器。本文是两个部分的第二篇,前者是理解 OPML 格式,此篇是解析此格式:概念篇解析篇(本文)本文内容OPML 格式创建适用于 RSS 的简易 OPML...原创 2020-02-29 14:22:27 · 2586 阅读 · 0 评论 -
只有你能 new 出来!.NET 隐藏构造函数的 n 种方法(Builder Pattern / 构造器模式)
如果你给类写了一个公有构造函数,那么这个类就能被其他开发者 new 出来。如果你不想让他们 new 出来,把构造函数 private 就好了呀。然而还有更多奇怪的方式来隐藏你类的构造方法。为什么要隐藏构造函数?有些类型,只有组件的设计者才知道如何正确创建其类型的实例,多数开发者都无法正确将其创建出来。典型的如 string:绝大多数开发者都不能正确创建出 string 的实例,但通过写一...原创 2020-02-29 14:20:18 · 605 阅读 · 0 评论 -
使用 Postman 调试 ASP.NET Core 开发的 API
使用 ASP.NET Core 开发简单的后台 API 还是非常容易的。涉及到 GET 请求的调试我们可以用浏览器简单搞定,那么 POST/PUT/DELETE 这样的请求呢?本文将使用 Postman 来调试这些请求。本文内容简单的 ASP.NET Core 程序模拟 GET 请求下载安装 Postman模拟 POST 请求模拟 PUT / PATCH / DELETE / … 请求关于本...原创 2020-02-29 14:15:40 · 2147 阅读 · 0 评论 -
.NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
这里我想说的是类型“实例”的缓存,适用于那些实例或者值计算很耗时的操作。典型的场景如反射获取 Attribute。本文内容适用思路代码用法高性能创建对象高性能为属性赋值高性能“反射”调用函数附代码适用本文推荐的方法适用于相同的输入可以获得相同的输出,但是这个输入到输出的过程非常耗时。大家都知道反射是很耗时的,尤其是获取 Attribute 和反射调用实例的方法。而从一个反射的成员中得到其...原创 2020-02-29 14:12:19 · 893 阅读 · 0 评论 -
使用 C# 代码创建快捷方式文件
快捷方式是一种特殊的文件,扩展名为 lnk。有很多种方式来创建快捷方式,不过使用 C# 代码创建一个却并不那么容易。本文分享三种不同的方式创建快捷方式。随处可用的代码这是最方便的方式了,因为这段代码随便放到一段代码中就能运行:/// <summary>/// 为当前正在运行的程序创建一个快捷方式。/// </summary>/// <param nam...原创 2020-02-29 13:58:38 · 1288 阅读 · 0 评论 -
.NET/C# 使窗口永不激活(No Activate 永不获得焦点)
有些窗口天生就是为了辅助其它程序而使用的,典型的如“输入法窗口”。这些窗口不希望抢夺其它窗口的焦点。有 Win32 方法来解决这样的问题,WS_EX_NOACTIVATE 便是关键。具体来说,是给窗口样式中额外添加一个 WS_EX_NOACTIVATE 位。var handle = GetTheWindowHandle();int exstyle = GetWindowLong(hand...原创 2020-02-29 13:48:57 · 1251 阅读 · 1 评论 -
使用 PInvoke.net Visual Studio Extension 辅助编写 Win32 函数签名
在 .NET 程序中使用 Win32 函数并不如 C++ 中方便。因为 C# 中不能引入 C++ 中常用的头文件,于是各种方法签名、结构体定义等等都需要各种寻找。然而 PInvoke.net 帮助我们解决了这个问题。本文推荐一款 Visual Studio 插件来帮助我们更快速地插入 Win32 函数签名。本文内容PInvoke.net使用 PInvoke.net 扩展PInvoke.net...原创 2020-02-29 13:41:53 · 976 阅读 · 1 评论 -
如何在 .NET/C# 代码中安全地结束掉一个控制台应用程序?通过发送 Ctrl+C 信号来结束
我的电脑上每天会跑一大堆控制台程序,于是管理这些程序的运行就成了一个问题。或者说你可能也在考虑启动一个控制台程序来完成某些特定的任务。如果我们需要结束掉这个控制台程序怎么做呢?直接杀进程吗?这样很容易出问题。我正在使用的一个控制台程序会写文件,如果直接杀进程可能导致数据没能写入到文件。所以本文介绍如何使用 .NET/C# 代码向控制台程序发送 Ctrl+C 来安全地结束掉程序。本文内容用 C...原创 2020-01-28 17:56:00 · 4443 阅读 · 1 评论 -
Sdk 风格的 csproj 对 WPF/UWP 支持不太好?有第三方 SDK 可以用!MSBuild.Sdk.Extras
自从微软推出 .NET Core 以来,新的项目文件格式以其优秀的可扩展性正吸引着更多项目采用。然而——微软官方的 WPF/UWP 项目模板依然还在采用旧的 csproj 格式!这只是因为——在 .NET Core 3.0 以前,基于 Microsoft.NET.Sdk 的官方 SDK 依然对 WPF/UWP 支持不够友好。本文内容为什么要使用第三方的 SDK?如何使用 MSBuild.Sd...原创 2020-01-28 17:21:13 · 883 阅读 · 0 评论 -
推荐 .NET/C# 开发者安装的几款代码分析插件或对应的代码分析 NuGet 包
如果你使用的是旧版本的 Visual Studio,那么默认的代码分析规则集是“最小建议规则集”。基于这个,写出来的代码其实只能说是能跑通过而已。随着 Roslyn 的发布,带来了越来越多更强大的代码分析器,可以为编写高质量的代码带来更多的帮助。作为 .NET/C# 开发者,强烈建议安装本文推荐的几款代码分析器。本文内容推荐类型简介Visual Studio 2019 自带的分析器Micro...原创 2019-12-30 08:49:39 · 2614 阅读 · 0 评论 -
如何将一个 .NET 对象序列化为 HTTP GET 的请求字符串
HTTP GET 请求时携带的参数直接在 URL 中,形式如 ?key1=value&key2=value&key3=value。如果是 POST 请求时,我们可以使用一些库序列化为 json 格式作为 BODY 发送,那么 GET 请求呢?有可以直接将其序列化为 HTTP GET 请求的 query 字符串的吗?本文内容HTTP GET 请求库?方法HTTP GET 请求...原创 2019-12-30 08:42:57 · 588 阅读 · 0 评论 -
一个简单的方法:截取子类名称中不包含基类后缀的部分
基类是 MenuItem,子类是 WalterlvMenuItem、FooMenuItem。基类是 Configuration,子类是 WalterlvConfiguration、ExtensionConfiguration。在代码中,我们可能会为了能够一眼看清类之间的继承(从属)关系而在子类名称后缀中带上基类的名称。但是由于这种情况下的基类不参与实际的业务,所以对外(文件/网络)的名称通常不需要...原创 2019-12-30 08:35:36 · 182 阅读 · 0 评论 -
C# 8.0 的可空引用类型,不止是加个问号哦!你还有很多种不同的可空玩法
C# 8.0 引入了可空引用类型,你可以通过 ? 为字段、属性、方法参数、返回值等添加是否可为 null 的特性。但是如果你真的在把你原有的旧项目迁移到可空类型的时候,你就会发现情况远比你想象当中复杂,因为你写的代码可能只在部分情况下可空,部分情况下不可空;或者传入空时才可为空,传入非空时则不可为空。本文内容C# 8.0 可空特性更灵活控制的可空特性输入:`AllowNull`输入:`Dis...原创 2019-12-30 08:35:07 · 3930 阅读 · 1 评论 -
C#/.NET 当我们在写事件 += 和 -= 的时候,方法是如何转换成事件处理器的
当我们在写 += 和 -= 事件的时候,我们会在 += 或 -= 的右边写上事件处理函数。我们可以写很多种不同的事件处理函数的形式,那么这些形式都是一样的吗?如果你不注意,可能出现内存泄漏问题。本文将讲解事件处理函数的不同形式,理解了这些可以避免编写代码的时候出现内存相关的问题。本文内容典型的事件处理函数变种事件处理函数编译器类型转换不是同一个委托实例`+=` `-=` 是怎么做的`-=`...原创 2019-12-30 08:27:43 · 1720 阅读 · 0 评论 -
.NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
我们知道,32 位程序在读取注册表的时候,会自动将注册表的路径映射到 32 位路径下,即在 Wow6432Node 子节点下。但是 64 位程序不会映射到 32 位路径下。那么 64 位程序如何读取到 32 位程序写入的注册表路径呢?本文内容Wow6432Node如何在 64 位程序中读取 32 位注册表路径Walterlv.Win32Wow6432Node对于 32 位程序,读取注册表...原创 2019-12-30 08:25:28 · 836 阅读 · 0 评论 -
.NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
我们知道 Windows 系统 NTFS 文件系统提供了硬连接功能,可以通过 mklink 命令开启。如果能够通过代码实现,那么我们能够做更多有趣的事情。本文提供使用 .NET/C# 代码创建 NTFS 文件系统的硬连接功能(目录联接)。本文内容目录联接使用 .NET/C# 实现使用 JunctionPoint目录联接以管理员权限启动 CMD(命令提示符),输入 mklink 命令可以得...原创 2019-12-30 08:05:28 · 949 阅读 · 0 评论 -
WPF 高性能位图渲染 WriteableBitmap 及其高性能用法示例
WPF 渲染框架并没有对外提供多少可以完全控制渲染的部分,目前可以做的有:D3DImage,用来承载使用 DirectX 各个版本渲染内容的控件WriteableBitmap,通过一段内存空间来指定如何渲染一个位图的图片HwndHost,通过承载一个子窗口以便能叠加任何种类渲染的控件本文将解释如何最大程度压榨 WriteableBitmap 在 WPF 下的性能。本文内容如何使用 ...原创 2019-12-30 08:04:27 · 8338 阅读 · 0 评论 -
如何在 .NET 项目中开启不安全代码(以便启用 unsafe fixed 等关键字)
有小伙伴希望在 .NET 代码中使用指针,操作非托管资源,于是可能使用到 unsafe fixed 关键字。但使用此关键字的前提是需要在项目中开启不安全代码。本文介绍如何在项目中开启不安全代码。本文内容入门方法高级方法临时方法其他说明入门方法第一步:在你需要启用不安全代码的项目上点击右键,然后选择属性:第二步:在“生成”标签下,勾选上“允许不安全代码”:第三步:切换到 Relea...原创 2019-12-30 08:02:43 · 2497 阅读 · 1 评论 -
使用 .editorconfig 配置 .NET/C# 项目的代码分析规则的严重程度
随着 Visual Studio 2019 更新,在 Visual Studio 中编写代码的时候也带来了基于 Roslyn 的代码质量分析。有一些代码分析严重程度可能与团队约定的不一致,这时就需要配置规则的严重程度。另外如果是个人使用插件安装了分析器,也可以配置一些严重程度满足个人的喜好。本文介绍使用 .editorconfig 文件来配置 .NET/C# 项目中,代码分析规则的严重性。可以是...原创 2019-12-30 08:01:38 · 1747 阅读 · 0 评论 -
Windows 系统上用 .NET/C# 查找所有窗口,并获得窗口的标题、位置、尺寸、最小化、可见性等各种状态
在 Windows 应用开发中,如果需要操作其他的窗口,那么可以使用 EnumWindows 这个 API 来枚举这些窗口。你可以使用本文编写的一个类型,查找到所有窗口中你关心的信息。本文内容需要使用的 API枚举所有窗口附源码需要使用的 API枚举所有窗口仅需要使用到 EnumWindows,其中需要定义一个委托 WndEnumProc 作为传入参数的类型。剩下的我们需要其他各种方法...原创 2019-11-27 08:01:00 · 5584 阅读 · 2 评论 -
.NET/C# 检测电脑上安装的 .NET Framework 的版本
如果你希望知道某台计算机上安装了哪些版本的 .NET Framework,那么正好本文可以帮助你解决问题。本文内容如何找到已安装的 .NET Framework注册表位置和含义读取注册表如何找到已安装的 .NET Framework有的电脑的 .NET Framework 是自带的,有的是操作系统自带的。这样,你就不能通过控制面板的“卸载程序”去找到到底安装了哪个版本的 .NET Fram...原创 2019-11-27 07:59:50 · 3408 阅读 · 0 评论 -
WPF 程序如何移动焦点到其他控件
WPF 中可以使用 UIElement.Focus() 将焦点设置到某个特定的控件,也可以使用 TraversalRequest 仅仅移动焦点。本文介绍如何在 WPF 程序中控制控件的焦点。本文内容`UIElement.Focus``TraversalRequest`关于逻辑焦点和键盘焦点跨窗口/跨进程切换焦点UIElement.Focus仅仅需要在任何一个控件上调用 Focus() 方法...原创 2019-11-27 07:50:30 · 2874 阅读 · 0 评论 -
.NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
弱引用是 .NET 引入的概念,可以用来协助解决内存泄漏问题。然而事件也可能带来内存泄漏问题,是否有弱事件机制可以使用呢?.NET 没有自带的弱事件机制,但其中的一个子集 WPF 带了。然而我们不是什么项目都能引用 WPF 框架类库的。本文介绍 Walterlv.WeakEvents 库来定义和使用弱事件。本文内容下载安装 Walterlv.WeakEvents定义弱事件使用弱事件系列博客...原创 2019-11-27 07:47:03 · 345 阅读 · 0 评论 -
.NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
弱引用是 .NET 引入的概念,可以用来协助解决内存泄漏问题。然而事件也可能带来内存泄漏问题,是否有弱事件机制可以使用呢?.NET 没有自带的弱事件机制,但其中的一个子集 WPF 带了。然而我们不是什么项目都能引用 WPF 框架类库的。网上有很多弱事件的 NuGet 包,不过仅仅支持定义事件的时候写成弱事件而不支持让任意事件变成弱事件,并且存在性能问题。本文介绍 Walterlv.WeakEve...原创 2019-11-27 07:45:45 · 322 阅读 · 0 评论