再学Blazor——扩展方法
上篇提到 Blazor 组件的高级写法,是采用扩展方法对 HTML 元素和组件进行扩展,以便于书写组件结构和代码阅读。本篇主要介绍扩展方法实现的思路。
- 什么是扩展方法
- 要扩展哪个类
- 扩展方法的实现
1. 什么是扩展方法
若要对一个 C# 类型添加新方法,一是修改源码,二是派生类,三是扩展方法。前两者不是万能的,第一种我们不一定有源码,第二种类型不一定能继承,只有第三种是万能的方法,在项目中新建一个扩展类型即可对任何类型进行扩展。
一个扩展方法需要有如下条件:
- 添加扩展类,类必须声明 static 修饰符
- 添加方法,方法必须声明 static 修饰符
- 方法第一个参数必须是扩展类型,且要有 this 关键字
//扩展类型 static class Extension { static void SayHello (this string name) { Console.WriteLine($"Hello, I'm {name}."); } } //测试 var name = "Known"; name.SayHello(); //输出 Hello, I'm Known.
2. 要扩展哪个类
上篇提到组件的高级写法,需要覆写组件的 BuildRenderTree 方法,这个方法有唯一类型参数 RenderTreeBuilder,对,就是这个类型,我们从它开始扩展一切 HTML 基本元素及自定义组件。
下面看看 RenderTreeBuilder 有哪些原生方法。
- OpenElement,打开一个元素,呈现
<div>
等开始标签 - CloseElement,关闭一个元素,呈现
</div>
等关闭标签 - OpenComponent,打开一个组件,呈现
<MyComponent>
- CloseComponent,关闭一个组件,呈现
</MyComponent>
- AddAttribute,添加元素和组件的属性,有8个重载方法
- AddMultipleAttributes,一次性添加多个属性,参数为字典类型
- AddContent,添加标签内部的内容,有6个重载方法
- AddMarkupContent,添加原始 HTML 字符内容
- AddElementReferenceCapture,添加元素对象参考,通过它可获取元素对象的实例
- AddComponentReferenceCapture,添加组件对象参考,通过它可获取组件对象的实例
掌握以上这些方法的使用后,我们就可以开发扩展我们需要的元素和组件。
3. 扩展方法的实现
由于 HTML 元素标签及其属性众多,为了方便且全面适配所有属性,增加一个属性建造者类型 AttributeBuilder 来管理元素属性。建造者类型如下:
public class AttributeBuilder { private readonly RenderTreeBuilder builder; public AttributeBuilder(RenderTreeBuilder builder) { this.builder = builder; } public AttributeBuilder Add(string name, object value) { if (value != null) builder.AddAttribute(1, name, value); return this; } public AttributeBuilder Id(string id) => Add("id", id); public AttributeBuilder Name(string name) => Add("name", name); ... }
添加一个 HTML 元素扩展类,用于扩展 HTML 元素,代码示例如下:
public static class HtmlExtension { //通用元素扩展方法 public static void Element(this RenderTreeBuilder builder, string name, Action<AttributeBuilder> child = null) { builder.OpenElement(0, name); var attr = new AttributeBuilder(builder); child?.Invoke(attr); builder.CloseElement(); } //div标签 public static void Div(this RenderTreeBuilder builder, Action<AttributeBuilder> child) => builder.Element("div", child); ... }
下面写一个元素扩展方法的示例,并将呈现的 HTML 结构与 C# 代码进行比对,直观感受一下高级写法的妙处。
protected override void BuildRenderTree(RenderTreeBuilder builder) { builder.Div(attr => //<div id="myPanel" class="panel"> { // attr.Id("myPanel").Class("panel"); // builder.Div(attr => // <div class="header"> { // attr.Class("header"); // //这里构造 Panel 头部内容 // }); // </div> builder.Div(attr => // <div class="body"> { // attr.Class("body"); // //这里构造 Panel 身体内容 // }); // </div> }); //</div> }
再次优化一下扩展方法的示例,下面代码看起来是不是更整齐了一些。
protected override void BuildRenderTree(RenderTreeBuilder builder) { builder.Div("myPanel", "panel", attr => //<div id="myPanel" class="panel"> { // builder.Div("header", attr => // <div class="header"> { // //这里构造 Panel 头部内容 // }); // </div> builder.Div("body", attr => // <div class="body"> { // //这里构造 Panel 身体内容 // }); // </div> }); //</div> }
分类:
00 Blazor
Known 是基于 Blazor 轻量级、跨平台、低代码、易扩展的插件开发框架。
源码:https://gitee.com/known/Known
源码:https://github.com/known/Known
如果对您有帮助,点击⭐Star⭐关注 ,感谢支持开源!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器