簡體   English   中英

C# Interactive 中對象的自定義打印

[英]Custom print of object in C# Interactive

考慮這個MCVE類:

public class Foo<T>
{
    private readonly T value;

    public Foo(T value)
    {
        this.value = value;
    }
}

當我在C# Interactive 中評估和打印這樣的對象時,它看起來像這樣:

> new Foo<string>("bar")
Foo<string> { }

那沒用。 我希望它看起來像這樣:

Foo<string> { "bar" }

我該怎么做?

我試過像這樣覆蓋ToString

public override string ToString()
{
    return $"Foo{typeof(T)} {{ {value} }}";
}

這不會產生我想要的:

> new Foo<string>("bar")
[Foo<System.String> { bar }]

此輸出至少存在三個問題:

  1. 該值不在引號中。 我希望它是"bar"而不是bar
  2. 類型參數顯示為System.String而不是string
  3. 整個值用方括號括起來。 這是我最不擔心的。

有沒有辦法讓 C# 交互式顯示具有自定義格式的對象?

我知道我可以向類添加公共屬性以顯示值,但由於封裝問題,我不想這樣做。 不過,要清楚的是,這就是我的意思:

public class Foo<T>
{
    public Foo(T value)
    {
        Value = value;
    }

    public T Value { get; }
}

這打印更接近我想要的:

> new Foo<string>("bar")
Foo<string> { Value="bar" }

但是,正如我所寫,我不想添加公共屬性。

我如何讓它表現得像下面這樣?

> new Foo<string>("bar")
Foo<string> { "bar" }
> new Foo<int>(42)
Foo<int> { 42 }

請注意,當使用字符串(例如int )以外的任何其他內容時,不應有引號。

您可以使用[DebuggerDisplay]屬性來自定義對象打印。 除了覆蓋ToString() ,您還可以在此屬性中使用任何方法/屬性。 例如:

[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
public class Foo<T>
{
    private readonly T value;

    public Foo(T value)
    {
        this.value = value;
    }

    private string GetDebuggerDisplay()
    {
        var val = value is string ? "\"" + value + "\"" : value?.ToString();
        return $"Foo<{typeof(T).Name.ToLower()}> {{ {val} }}";
    }
}

這避免了必須覆蓋ToString()或使用不同的實現。 如返回T value的字符串表示。

您需要添加一個 switch/case 來將類名(例如Int32int

[DebuggerDisplay]屬性的nq部分刪除了 value 周圍的引號

結果如下:

> new Foo<string>("bar")
Foo<string> { "bar" }

如需進一步參考,請查看 Jared Parson 關於[DebuggerDisplay]屬性的優秀博客文章: https : //blogs.msdn.microsoft.com/jaredpar/2011/03/18/debuggerdisplay-attribute-best-practices/

如果您可以像第一次嘗試那樣覆蓋ToString() ,那么您可以在那里做任何您喜歡的事情。 這讓你更接近你想要的,你可以根據需要修改它:

public override string ToString()
{
    string v = value is string ? $"\"{value}\"" : $"{value}";
    string t = typeof(T).Name.ToLower();
    return $"Foo<{t}> {{ {v} }}";
}

正如 Kristian Hellang 所建議的,這可以通過向類添加[DebuggerDisplay]屬性來簡單輕松地解決:

[DebuggerDisplay("{ value }")]
public class Foo<T>
{
    private readonly T value;

    public Foo(T value)
    {
        this.value = value;
    }
}

這解決了所有問題:

> new Foo<string>("bar")
Foo<string>("bar")
> new Foo<int>(42)
Foo<int>(42)
> new Foo<DateTime>(new DateTime(2018, 4, 23))
Foo<DateTime>([23.04.2018 00:00:00])

渲染不使用大括號,而是使用構造函數指示的普通括號,但我只覺得合適。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM