You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LINQPad中创建超链接/按钮以展开关联数据表格?

在LINQPad中给Dump的对象引用添加跳转高亮功能

不用弃用标准Dump方法,也不需要从零构建HTML,借助LINQPad的Util库和内置脚本功能就能实现引用的跳转与高亮。

核心实现逻辑

LINQPad会给每个通过Dump()输出的对象分配唯一的DOM标识,结合客户端内置的脚本函数,就能定位并操作目标元素:

  • linqpad.navigateToDumpId(id):滚动到目标对象的Dump区域
  • linqpad.highlightDumpId(id):高亮目标元素
  • 通过Util.Html()生成带点击事件的链接,替代默认的引用文本显示

具体实现方案

方案1:扩展方法实现带链接的自定义Dump

给你的容器类和项目类添加扩展方法,在保留原生Dump布局的同时,替换引用为可点击链接:

public static class DumpLinkExtensions
{
    // 对外暴露的自定义Dump方法
    public static void DumpWithReferences(this object obj, string title = null)
    {
        // 先执行原生Dump,确保对象已生成DOM元素
        var dumpResult = obj.Dump(title);
        
        // 根据对象类型处理引用属性
        if (obj is Item item)
        {
            HandleItemReferences(item);
        }
        else if (obj is Container container)
        {
            HandleContainerReferences(container);
        }
    }

    // 处理Item类的引用
    private static void HandleItemReferences(Item item)
    {
        if (item.ReferencedItem != null)
        {
            var targetId = item.ReferencedItem.GetDumpId();
            Util.Html($"<a href='#' onclick='linqpad.navigateToDumpId({targetId}); linqpad.highlightDumpId({targetId});'>引用项目:{item.ReferencedItem.Name}</a>")
                .Dump("关联项目");
        }

        if (item.ReferencedContainer != null)
        {
            var targetId = item.ReferencedContainer.GetDumpId();
            Util.Html($"<a href='#' onclick='linqpad.navigateToDumpId({targetId}); linqpad.highlightDumpId({targetId});'>引用容器:{item.ReferencedContainer.Name}</a>")
                .Dump("关联容器");
        }
    }

    // 处理Container类的引用
    private static void HandleContainerReferences(Container container)
    {
        foreach (var item in container.Items)
        {
            if (item.ReferencedItem != null)
            {
                var targetId = item.ReferencedItem.GetDumpId();
                Util.Html($"<a href='#' onclick='linqpad.navigateToDumpId({targetId}); linqpad.highlightDumpId({targetId});'>{item.Name} -> {item.ReferencedItem.Name}</a>")
                    .Dump("项目引用关系");
            }
        }
    }

    // 反射获取LINQPad内部分配的Dump ID
    private static int GetDumpId(this object obj)
    {
        var getDumpIdMethod = typeof(LINQPad.Util)
            .GetMethod("GetDumpId", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
        
        return (int)getDumpIdMethod.Invoke(null, new[] { obj });
    }
}

// 示例对象结构
public class Container
{
    public string Name { get; set; }
    public List<Item> Items { get; set; } = new();
}

public class Item
{
    public string Name { get; set; }
    public Item ReferencedItem { get; set; }
    public Container ReferencedContainer { get; set; }
}

使用时直接调用:

var containerA = new Container { Name = "容器A" };
var item1 = new Item { Name = "项目1" };
var item2 = new Item { Name = "项目2", ReferencedItem = item1, ReferencedContainer = containerA };
containerA.Items.AddRange(new[] { item1, item2 });

containerA.DumpWithReferences("带引用跳转的容器");

方案2:实现IDumpable接口重写默认Dump

如果希望调用原生Dump()就自动生成链接,可以让你的类实现LINQPad的IDumpable接口:

public class Item : IDumpable
{
    public string Name { get; set; }
    public Item ReferencedItem { get; set; }
    public Container ReferencedContainer { get; set; }

    public void Dump()
    {
        // 用Util.Table自定义输出结构,替换引用为链接
        Util.Table(new
        {
            名称 = Name,
            关联项目 = ReferencedItem != null ? 
                Util.Html($"<a href='#' onclick='linqpad.navigateToDumpId({ReferencedItem.GetDumpId()}); linqpad.highlightDumpId({ReferencedItem.GetDumpId()});'>{ReferencedItem.Name}</a>") : "无",
            关联容器 = ReferencedContainer != null ?
                Util.Html($"<a href='#' onclick='linqpad.navigateToDumpId({ReferencedContainer.GetDumpId()}); linqpad.highlightDumpId({ReferencedContainer.GetDumpId()});'>{ReferencedContainer.Name}</a>") : "无"
        }).Dump();
    }
}

// 同样给Container实现IDumpable
public class Container : IDumpable
{
    public string Name { get; set; }
    public List<Item> Items { get; set; } = new();

    public void Dump()
    {
        Util.Table(new
        {
            容器名称 = Name,
            包含项目 = Items.Count
        }).Dump();
        
        // 输出项目列表并处理引用
        foreach (var item in Items)
        {
            item.Dump();
        }
    }
}

使用时直接调用原生Dump()即可:

containerA.Dump();

关键注意点

  • 引用的目标对象必须先通过Dump()生成DOM元素,否则navigateToDumpId无法定位
  • GetDumpId借助反射调用LINQPad内部方法,大部分稳定版本都兼容,若版本更新后失效,可通过LINQPad的官方文档调整获取ID的方式
  • 可根据实际对象结构扩展引用遍历逻辑,支持多层嵌套、跨容器引用等复杂场景

内容的提问来源于stack exchange,提问作者bracco23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 07:18:10