为什么LinqPad在转储某些类型时会运行ToString()方法?

5
我将使用LinqPad中NuGet.Versioning包中的NuGetVersion。我想要使用Dump()方法来检查其属性,但是得到的只是这个对象的字符串表示而不是通常意义上的Dump。例如:
var v = new NuGetVersion("1.0.0");
v.Dump();

在输出窗口中显示以下内容:
1.0.0

有人知道为什么 LinqPad 在转储某些类型时运行 ToString(),以及如何更改此行为吗?


1
你确定这不是唯一的公共属性吗?我认为 Dump() 只是用于转储不继承自某个已知类型的对象的公共属性。 - flindeberg
是的,它有一些公共属性。源代码在这里: https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Versioning/NuGetVersion.cs - Kevin Kuszyk
我认为只有 Joe 能够回答这个问题。 - Gert Arnold
1个回答

7
一般来说,如果对象实现了 System.IFormattable 接口,LINQPad 会调用 ToString() 方法而不是展开属性。
您可以编写一个扩展方法放在我的扩展中,并使用 LINQPad 的 ICustomMemberProvider 来覆盖此行为。 编辑:现在有更简单的方法。调用 LINQPad 的 Util.ToExpando() 方法即可。
var v = new NuGetVersion("1.0.0");
Util.ToExpando (v).Dump();

(Util.ToExpando将对象转换为ExpandoObject。)

供参考,以下是使用ICustomMemberProivder的旧解决方案:

static class MyExtensions
{
    public static object ForceExpand<T> (this T value)
        => value == null ? null : new Expanded<T> (value);

    class Expanded<T> : ICustomMemberProvider
    {
        object _instance;
        PropertyInfo[] _props;

        public Expanded (object instance)
        {
            _instance = instance;
            _props = _instance.GetType().GetProperties();
        }

        public IEnumerable<string> GetNames() => _props.Select (p => p.Name);
        public IEnumerable<Type> GetTypes () => _props.Select (p => p.PropertyType);
        public IEnumerable<object> GetValues () => _props.Select (p => p.GetValue (_instance));
    }
}

这样调用:

new NuGetVersion("1.2.3.4").ForceExpand().Dump();

谢谢Joe。你会考虑添加一个重载来做这个吗?就像 v.Dump(forceExpand: true); 这样的东西? - Kevin Kuszyk
像上面这样的ForceExpand()方法相对于Dump重载的优点在于它可以针对单个属性进行指定。 - Joe Albahari
请注意,ICustomMemberProvider在该链接中已不再有文档说明。 - NetMage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接