【问题标题】:How to pretty print the Iterator Method如何漂亮地打印迭代器方法
【发布时间】:2014-12-31 09:25:24
【问题描述】:

我想获取带有 Iterator Method 参数的方法名称,我正在努力寻找一个简单的解决方案。迭代器是由编译器生成的,因此源方法名和它的参数现在分别在生成的类名和它的字段中(带有一些神奇的 +_d 符号)。

在 Visual Studio 的即时窗口中,当我输入迭代器方法时,我会以一种漂亮的方式获得方法名称及其参数。他们是在使用一些定制打印机,还是有一些帮手可以做到这一点?

编辑:

主要目标是获取协程异步调用栈。

Program.Test(a, b)
  Program.TestB(b)

这是一个例子:

using System;
using System.Collections;
using System.Linq;

class Program
{
    static IEnumerable TestB(string b)
    {
        yield return b;
        yield return b;
    }

    static IEnumerable Test(string a, string b)
    {
        yield return a;
        yield return TestB(b);
    }

    static void Main(string[] args)
    {
        var iterator = Test("foo", "bar");

        // Immediate Window
        // ================
        // iterator
        // {Program.Test}
        //     a: null
        //     b: null
        //     System.Collections.Generic.IEnumerator<System.Object>.Current: null
        //     System.Collections.IEnumerator.Current: null

        Console.WriteLine(iterator);
        // prints:
        // Program+<Test>d__0

        foreach (var field in iterator.GetType().GetFields())
            Console.WriteLine(field);
        // prints:
        // System.String a
        // System.String <>3__a
        // System.String b
        // System.String <>3__b
    }
}

【问题讨论】:

  • 不清楚你所说的“漂亮的印刷品”是什么意思。您期望的输出是什么?
  • 我想得到方法名和它的参数。
  • 目标是打印:Program.Test(a, b)
  • 但是你刚刚得到了调用方法的结果。虽然您可以通过尝试将类型的名称与方法匹配来做到这一点,但您必须考虑如果方法重载会发生什么 - 以及您想要做什么如果该方法的实现更改为以后不使用迭代器块。 (假设您决定改用 LINQ,例如...)
  • 我使用迭代的方法来实现协程。这个漂亮的打印将允许以与普通调用堆栈相同的方式获取异步调用堆栈。我想我应该用一些正则表达式来进行上述反思......

标签: c# visual-studio yield coroutine object-dumper


【解决方案1】:

您可以使用DebuggerTypeProxy 属性并将其设置在您的Program 类上。这将与MSDN documentation page 中给出的示例非常相似,该示例显示了如何显示 HashTable,而不是 Enumarable。将其转换为使用 Enumerable 应该相当容易。您可能需要创建自己的继承自 IEnumerable 的类才能使其正常工作。不确定它是否适用于隐式枚举,但话又说回来,你在这里走捷径并想要糖衣,这些通常不能很好地结合在一起。

[DebuggerDisplay("{value}", Name = "{key}")]
internal class KeyValuePairs
{
    private IDictionary dictionary;
    private object key;
    private object value;

    public KeyValuePairs(IDictionary dictionary, object key, object value)
    {
        this.value = value;
        this.key = key;
        this.dictionary = dictionary;
    }
}

[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable : Hashtable //this would be Program
{
    private const string TestString = "This should not appear in the debug window.";

    internal class HashtableDebugView
    {
        private Hashtable hashtable;
        public const string TestString = "This should appear in the debug window.";
        public HashtableDebugView(Hashtable hashtable)
        {
            this.hashtable = hashtable;
        }

        [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
        public KeyValuePairs[] Keys
        {
            get
            {
                KeyValuePairs[] keys = new KeyValuePairs[hashtable.Count];

                int i = 0;
                foreach(object key in hashtable.Keys)
                {
                    keys[i] = new KeyValuePairs(hashtable, key, hashtable[key]);
                    i++;
                }
                return keys;
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-02-04
    • 2021-01-08
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2012-10-08
    • 2011-07-28
    • 2015-02-07
    相关资源
    最近更新 更多