【问题标题】:How can I dump the normal properties on an IEnumerable in Linqpad如何在 Linqpad 的 IEnumerable 上转储正常属性
【发布时间】:2010-10-21 14:40:41
【问题描述】:

如果我有一个对象,其中包括一个 IEnumerable,并且我转储此对象,我会得到枚举值。

有没有办法让 Linqpad 列出其他属性:

下面的例子: 我可以让 Dump 包含 Hello 和 digits 属性吗?

void Main()
{
    var t = new test();
    var d = new Dictionary<string,string> {{"Hello","World"},{"Good by","Sky"}};

    t.Dump();
    d.Dump();
}

// Define other methods and classes here

public class test : IEnumerable
{
    public string Hello { get { return "World"; }}
    public List<int> digits { get { return new List<int> {0,1,2,3,4,5,6,7,8,9}; }}

    public IEnumerator GetEnumerator() { yield return "Hej"; }
}

【问题讨论】:

标签: ienumerable dump linqpad


【解决方案1】:

您可以编写一个 DumpPayload 扩展方法,如下所示:

void Main()
{
    var t = new test();
    t.DumpPayload();
}

public static class Extensions
{
    public static void DumpPayload (this IEnumerable o)
    {
        if (o == null)
        {
            o.Dump();
            return;
        }
        var d = new Dictionary<string,object>();        
        foreach (var member in o.GetType().GetProperties())
            try
            {
                d[member.Name] = member.GetValue (o, null);
            }
            catch (Exception ex)
            {
                d[member.Name] = ex;
            }           
        d["AsEnumerable"] = o;
        d.Dump();
    }   
}

如果您将此扩展方法放入“我的扩展”中,它将可供所有查询使用。

另一种解决方案是在测试类中实现ICustomMemberProvider:

public class test : IEnumerable, ICustomMemberProvider
{
    public string Hello { get { return "World"; }}
    public List<int> digits { get { return new List<int> {0,1,2,3,4,5,6,7,8,9}; }}

    public IEnumerator GetEnumerator() { yield return "Hej"; }

    IEnumerable<string> ICustomMemberProvider.GetNames() 
    {
        return "Hello Enumerator".Split();
    }

    IEnumerable<Type> ICustomMemberProvider.GetTypes ()
    {
        return new [] { typeof (string), typeof (IEnumerable) };
    }

    IEnumerable<object> ICustomMemberProvider.GetValues ()
    {
        return new object [] { Hello, this.OfType<Object>() };
    }   
}

请注意,如果测试类是在另一个程序集中定义的,则无需引用 LINQPad 即可实现ICustomMemberProvider。您只需将以下定义粘贴到您的项目中,LINQPad 就会选择它:

namespace LINQPad
{
   public interface ICustomMemberProvider
   {
      IEnumerable<string> GetNames ();
      IEnumerable<Type> GetTypes ();
      IEnumerable<object> GetValues ();
   }
}

【讨论】:

  • 这个答案值得更多的支持,当我有一个自定义类型为 ICollection (其中 self 是该类型)用于递归数据和继承自该自定义类型的子类时,ICustomMemberProvider 帮助了我。现在我的结构正确转储了!
【解决方案2】:

据我所知,如果您尝试转储的对象实现 IEnumerable,那么 LINQPad 总是希望将其转储为 IEnumerable 列表。摆脱接口正确显示转储信息中的Hellodigits 属性。

this link 开始,您似乎可以编写自己的转储,通过枚举集合 它的所有属性,然后将整个内容作为 XHTML 字符串输出,来完成类似 LINQPad 的操作。这个我没试过。

【讨论】:

  • 我接受了这个作为答案,因为它解释了 Dump 这样做的原因。我主要是看是否有可以使用的设置或参数。
【解决方案3】:

使用序列化器?

Json.NET 将以 json 格式为您完成所有这些工作。

Newtonsoft.Json.JsonConvert.SerializeObject(t, Newtonsoft.Json.Formatting.Indented)

如果你不想要 json,那么选择你想要的序列化器,或者你只需​​要做序列化器会做的事情,使用反射来迭代对象的属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多