取消

如何让 .NET Core 命令行程序接受密码的输入而不显示密码明文

如果是在 GUI 中要求用户输入密码,各 UI 框架基本都提供了用于输入密码的控件;在这些控件中,用户在输入密码的时候会显示掩码。然而对于控制台程序来说,并没有用于输入密码的原生方法。 本文将讲述一种在控制台中输入密码,并仅显示掩码的方法。 开始简单的程序 让我们开始一个简单的 .NET Core 控制台程序。 static void Main(string[] args) { ...

如何编写基于 Microsoft.NET.Sdk 的跨平台的 MSBuild Target(附各种自带的 Task)

我之前写过一篇 理解 C# 项目 csproj 文件格式的本质和编译流程,其中,Target 节点就是负责编译流程的最关键的节点。但因为篇幅限制,那篇文章不便详说。于是,我在本文说说 Target 节点。 Target 的节点结构 <Target> 内部几乎有着跟 <Project> 一样的节点结构,内部也可以放 PropertyGroup 和 ItemG...

C# 中那些可以被重载的运算符(操作符),以及使用它们的那些丧心病狂的语法糖

C# 中的运算符重载并不新鲜。然而,到底有哪些运算符可以重载,重载运算符可以用来做哪些丧心病狂的事情呢? 本文收集了 C# 中所有可以重载的运算符,并且利用他们做了一些丧心病狂的语法糖。 可以重载的运算符 运算符的重载比想象中的更加强大。因为——重载运算符时可以随意定义运算符中操作数的数据类型和返回值的类型。 是的!不只是操作数,连返回值类型也能被重载! 一元运算符 +,...

如何快速编写和调试 Emit 生成 IL 的代码

.NET Core/.NET Framework 的 System.Reflection.Emit 命名空间为我们提供了动态生成 IL 代码的能力。利用这项能力,我们能够在运行时生成一段代码/一个方法/一个类/一个程序集。 大家都知道反射的性能很差,通过缓存反射调用的方法则能够大幅提升性能。Emit 为我们提供了这项能力,我们能够在运行时生成一段代码,替代使用反射动态调用的代码,以提升性能...

UWP 流畅设计中的光照效果(容易的 RevealBorderBrush 和不那么容易的 RevealBackgroundBrush)

在 Windows 10.0.16299 中,RevealBrush 被引入,可以实现炫酷的鼠标滑过高亮效果和点击光照。本文将告诉大家如何完整地实现这样的效果。 Reveal 的效果(自带) 在微软官方推荐的 XAML Controls Gallery 应用中,我们可以找到 Reveal 的实现章节。下图是应用中演示的 Reveal 效果: 不过在其实现中,全都是使用的系统自带...

使用 MSBuild 响应文件 (rsp) 来指定 dotnet build 命令行编译时的大量参数

在为开源项目 dotnet-campus/MSTestEnhancer 进行持续集成编译时,需要在编译命令中传入较多的参数。这对于新接手此项目的人来说,成本还是高了一点儿。本文将介绍 MSBuild 响应文件 (MSBuild Response Files, *.rsp) 来优化命令行编译体验。 我们在 msbuild 命令中加入 /? 参数可以看到它对响应文件的解释: > d...

Roslyn 的确定性构建

注意到每次编译完之后,你的 dll 或者 exe 是不一样的吗?本来这并没有什么大不了的,但大家都知道数字和鹅厂的安全软件遍布在我们大(tiān)陆(cháo)地区的大量电脑上,它们的查杀策略是——凡是不认识的一律是病毒木马;于是每次不一样的编译很容易引起它们的警告——真不想每次都把编译后的样本提交给它们存档入库。 确定性编译 于是有一天意外地发现了 Roslyn 的确定性构建。...

(持续整理中)Visual Studio 中 C# 代码分析规则集中每一项的含义 (stylecop ruleset)

因为我希望在要求很高的库中及时发现潜在的代码问题,所以我开启了 Visual Studio 的代码分析。 但是在修改规则的时候发现规则的名称都是在用我懂的每一个字描述我一点都不懂的概念,于是打算一个个尝试以找出每一个代码分析的实际意义。 在整理的过程当中,发现要么是名称看不懂,要么是错误提示看不懂。不过两个合在一起并配合代码实验之后,基本上都能够看懂了。于是,把已经整理的部分都分享出来。...

生成代码,从 T 到 T1, T2, Tn —— 自动生成多个类型的泛型

当你想写一个泛型 <T> 的类型的时候,是否想过两个泛型参数、三个泛型参数、四个泛型参数或更多泛型参数的版本如何编写呢?是一个个编写?类小还好,类大了就杯具! 事实上,在 Visual Studio 中生成代码的手段很多,本文采用最笨的方式生成,但效果也很明显——代码写得轻松写得爽! 我们想要的效果 我们现在有一个泛型的版本: public class Demo&...

.NET Core 和 .NET Framework 中的 MEF2

MEF,Managed Extensibility Framework,现在已经发布了三个版本了,它们是 MEF 和 MEF2。 等等!3 去哪儿了?本文将教大家完成基于 MEF2 的开发。 MEF 和 MEF2 其实微软发布了四个版本的 MEF: 随着 .NET Framework 4.0 发布,微软称之为 MEF 随着 .NET Framework 4.5 发布...

C#/.NET 匿名函数会捕获变量,并延长对象的生命周期

小伙伴在一次垃圾回收中,发现对象并没有被回收掉,而注释掉一句代码后它便能够回收。 这究竟是为什么? 不关心探索过程的就直接拉到最后看结论吧! 探索 测试代码是这样的: private void OnLoaded(object sender, RoutedEventArgs e) { var variable = new MainPage(); var ref...

实现一个 WPF 版本的 ConnectedAnimation

Windows 10 的创造者更新为开发者们带来了 Connected Animation 连接动画,这也是 Fluent Design System 的一部分。它的视觉引导性很强,用户能够在它的帮助下迅速定位操作的对象。 不过,这是 UWP,而且还是 Windows 10 Creator’s Update 中才带来的特性,WPF 当然没有。于是,我自己写了一个“简易版本”。 ▲ ...

迫不及待地体验了一把 C#8.0 中的可空引用类型(Nullable Reference)

在我之前的一篇博客 NullReferenceException,就不应该存在! 中,我吐槽了 C# 中 null 的弊端以及避免 null 的方法;事实上这本都是现代高级语言中极力推崇的做法。Kotlin 和 Swift 自诞生之日起引用类型就不能为空,C# 背着历史的包袱直到 8.0 才开始这么做…… 安装可空引用类型预览包 现在 C#8.0 还没有发布,但微软已经提供了预览...

WPF 自定义键盘焦点样式(FocusVisualStyle)

WPF 自带的键盘焦点样式是与传统控件样式搭配的,但 WPF 凭着其强大的自定义样式的能力,做出与传统控件样式完全不同风格的 UI 简直易如反掌。这时,其自带的键盘焦点样式(FocusVisualStyle)就非常不搭了,改改会舒服得多。比如,改成 UWP 的样式。 本文将展示 WPF 自定义键盘焦点样式自定义的坑! ▲ WPF 自带的键盘焦点样式 ▲ UWP 暗主题键盘焦点样...

异步任务中的重新进入(Reentrancy)

一个按钮,点击执行一个任务。我们可能直接在它的 Click 事件中写下了执行任务的代码。 一般我们无需担心这样的代码会出现什么问题——但是,这样的好事情只对同步任务有效;一旦进入了异步世界,这便是无尽的 BUG! 重新进入(Reentrancy) private void Button_Click(object sender, RoutedEventArgs e) { ...

将 UWP 的有效像素(Effective Pixels)引入 WPF

在很久很久以前,WPF 诞生之初,有一个神奇的单位,它的名字叫做——设备无关单位(DIP,Device Independent Unit)。微软给它描绘了一片美好的愿景——在任何显示器上显示的尺寸是相同的。 What the ** is this unit!!! 神 TM 相同!!! UWP 采用有效像素(Effective Pixels)来描述尺寸,这是才是能够自圆其说的一套尺寸描述;...

WPF 跨应用程序域的 UI(Cross AppDomain UI)

为自己写的程序添加插件真的是一个相当常见的功能,然而如果只是简单加载程序集然后去执行程序集中的代码,会让宿主应用程序暴露在非常危险的境地!因为只要插件能够运行任何一行代码,就能将宿主应用程序修改得天翻地覆哭爹喊娘;而根本原因,就在于暴露了整个托管堆和整个 UI 树。 如果将宿主和插件放到不同的应用程序域中,则可以解决此问题。本文将介绍跨应用程序域承载 UI 的方法,其中也包含跨域(Cros...

Visual->UIElement->FrameworkElement,带来更多功能的同时也带来了更多的限制

在 WPF 或 UWP 中,我们平时开发所遇到的那些 UI 控件或组件,都直接或间接继承自 Framework。例如:Grid、StackPanel、Canvas、Border、Image、Button、Slider。我们总会自然而然地认为这些控件都是有大小的,它们会在合适的位置显示自己,通常不会超出去。但是,FrameworkElement 甚至是 Control 用得久了,都开始忘记 V...

DependencyProperty.UnsetValue 的正确打开方式

无论是 WPF,还是 UWP,只要你用了绑定或者标记扩展,一定会碰到一个神奇的值——DependencyProperty.UnsetValue。UnsetValue 是什么意思?为什么会出现这个值呢?如果要让 UnsetValue 为我们所用,正确的用法又是什么呢? DependencyProperty.UnsetValue 是什么? 要知道这是什么,一定要看源码: /// &lt...

用 AppContext 解决类库的更新兼容问题

还记得微软在 Mitigation: Pointer-based Touch and Stylus Support 中告诉大家如何在 .NET Framework 4.7 中迁移 WPF 的触控到基于 Pointer 消息?记得关键的 <AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.EnableP...

为 Visual Studio 使用通配符批量添加项目文件

通常大家都不会关心 Visual Studio 的项目文件里是如何记录这个项目所包含的所有文件的,因为各位开发者们早已经习惯于右键添加文件或者拖拽文件进项目了。但如果你在某一个文件夹中放了大量的文件(尤其是图片等资源文件),那么这时会卡很久才能拖进去,拖完之后如果还要批量修改生成操作,那真的是痛不欲生。 但是,Visual Studio 提供的项目文件(*.csproj)其实是支持通配符的...

深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分)

深耕 WPF 开发的各位程序员大大们一定避不开使用 Dispatcher。跨线程访问 UI 当然免不了用到它,将某个任务延迟到当前任务之后执行也会用到它。Dispatcher.Invoke、Dispatcher.BeginInvoke 是过去大家经常使用的方法,而 .NET Framework 4.5 中微软为我们带来了 Dispatcher.InvokeAsync 方法,它和前面两个有何不...

git 如何更可靠地解决冲突?

使用 git 合并代码时出现冲突是很常见的,不过如何解冲突才能更加可靠呢?不漏掉别人的修改,也同时让自己的修改完全保留。 本文将介绍利用各种工具更可靠地解决冲突。 使用 Visual Studio 如果你使用 Visual Studio,那么当合并两个分支出现冲突的时候,Visual Studio 的 Team Explorer 会显示当前冲突的所有文件。 ▲ 图 1 当...

使用 ReSharper,输入即遵循 StyleCop 的代码格式化规范

StyleCop 可以帮助强制执行代码格式化规范,ReSharper 可以帮助你更高效地编写代码。把两者结合起来,你便能高效地编写符合团队强制格式化规范的代码来。 本文就介绍如何使用 ReSharper 来高效地遵循 StyleCop 的代码格式化规范。 安装插件 StyleCop by JetBrains StyleCop by JetBrains 插件的开发名称是 Styl...

用 dotTrace 进行性能分析时,各种不同性能分析选项的含义和用途

对 .NET 程序进行性能分析,dotTrace 能应对绝大多数的场景。在开启一个进程进行性能分析之前,我们会看到一些性能分析选项(Profiler Options)。本文将介绍这几个选项的含义,并用实际的例子来说明其用途。 dotTrace 的性能分析选项 你可以前往 Download dotTrace: .NET Performance Profiler by JetBrai...

Win2D 中的游戏循环:CanvasAnimatedControl

Win2D 是 DirectX 的一个高层封装,提供了极大 DirectX 性能的同时,又具有很好用的 API 设计。 用 Win2D 除了能做出高性能的视觉效果之外,还可以轻而易举地搭建一个游戏循环出来。使用 Win2D 的游戏循环,你可以直接做出一个简单的游戏出来。 使用 Win2D 做出来的游戏 我在 GitHub 上开源了我正在做的一个基于 Win2D 的小游戏 —— ...

使用 Win2D 绘制带图片纹理的圆(或椭圆)

使用 Win2D 绘制图片和绘制椭圆都非常容易,可是如何使用 Win2D 绘制图片纹理的椭圆呢? 重力迷宫小球 ▲ 重力迷宫 你可以看到这个小球就像一个透明塑料小球一样,纹理会跟随背景而动。这显然不是 Win2D 中的游戏循环:CanvasAnimatedControl 一文中我用 DrawEllipse 画的那个灰色小球。 Win2D 实现 我们会使用到 Win2D 中...

如何在单元测试中使用 Dispatcher.Invoke/InvokeAsync?

对于部分涉及到 WPF UI 的部分,单元测试一般都难以进行。但是,如果只是使用到其中的 UI 线程调度,那就稍微容易一些。不过为了找到这个方法我做了很多天的尝试。 本文将提供一种在单元测试中运行 Dispatcher 的方法,以便能够在单元测试中测试到 Invoke/InvokeAsync 是否按要求执行。 我第一个想到的是在当前函数中执行 Dispatcher.Run,但是 Ru...

技术、产品、交流、思考 - 微软技术暨生态大会 2018

微软技术暨生态大会 2018(Microsoft Tech Summit 2018)已于 2018 年 10 月 25-27 日在上海世博中心召开。本文记录我们参会后的一些知识和思考。 路 2018 年 10 月 23 日中午,我和林德熙踏上了前往上海的旅程。这是德熙第一次进行如此长途的旅行,之前几乎一直待在家里。 微软技术暨生态大会是从 10 月 25 日到 10 月 27 ...

只有你能 new 出来!.NET 隐藏构造函数的 n 种方法(Builder Pattern / 构造器模式)

如果你给类写了一个公有构造函数,那么这个类就能被其他开发者 new 出来。如果你不想让他们 new 出来,把构造函数 private 就好了呀。 然而还有更多奇怪的方式来隐藏你类的构造方法。 为什么要隐藏构造函数? 有些类型,只有组件的设计者才知道如何正确创建其类型的实例,多数开发者都无法正确将其创建出来。典型的如 string:绝大多数开发者都不能正确创建出 string 的...