【问题标题】:How do I generate a ToString() in Visual Studio that includes all properties?如何在 Visual Studio 中生成包含所有属性的 ToString()?
【发布时间】:2019-10-30 10:03:38
【问题描述】:

我是一名 Java 开发人员,习惯于 Eclipse 中的“生成 toString()”选项,该选项提供完整的 toString,打印所有实例变量的值。我只是在 Visual Studio 中寻找类似的快捷方式。

我已经看到如何开始输入方法,“公共覆盖”和自动完成将存根 ToString() 但它不会用所有类属性填充它。

    public override string ToString()
        {
            return base.ToString();
        }

我希望生成的方法包含类的所有属性。

【问题讨论】:

  • ToString() 通常不会返回类的所有属性。它具有特定用途,您可以根据需要进行设置。但是您可以:键入属性 :)、使用反射、创建代码 sn-p(请参阅工具下的代码片段管理器)以实现它,使用提供此功能的第三方扩展。
  • 您想解决的实际问题是什么?该字符串会是什么样子以及如何使用它? 有意义的 格式是使用JSON 并使用例如Json.NET 的JConvert.SerializeObject 进行序列化。不过,这并不是一个好的 ToString() 格式。
  • ToString() 用于在调试器中显示字符串,例如在监视窗口中,当类型没有 DebuggerDisplay 属性时。使用您想要查看的格式添加该属性要好得多,而不是覆盖ToString()

标签: c# visual-studio tostring


【解决方案1】:

你可以使用 JSON.NET 来序列化你的类。

public override string ToString()
{
    return JsonConvert.SerializeObject(this);
}

【讨论】:

    【解决方案2】:

    选项 1:反射

    您可以通过使用反射来做到这一点。但是,如果您必须在短时间内频繁调用该方法,这可能会导致性能问题。使用反射进行编码也不是那么简单。



    选项 2:锐化器

    Visual Studio 插件 Resharper 具有此功能:

    alt + 插入 -> 生成 -> 格式化成员 -> 全选 -> 完成



    选项 3:Fody/ToString nuget 包

    当您只需要公共属性时,这可能是最简单的解决方案。它不适用于公共字段。

    【讨论】:

    • Fody 的不错选择。这是软件的非凡和平。我仍然会选择(2)
    • 谢谢!我肯定会尝试 Resharper。
    • resharper 选项很好,但像string.Join(", ", $"{nameof(Prop)}: {Prop}", ...) 那样做得更好
    • @xandermonkey 我不喜欢使用 string.join。在这种情况下更冗长。
    【解决方案3】:

    没有与您所说的 Java 和 Eclipse 相同的东西。

    @RawitasKrungkaew 的回答很好。

    如果你不想使用 JSON,可以使用反射和扩展方法来获得可重用性:

    在某个班级

    public override string ToString()
    {
      return this.GetPropertiesAsText();
    }
    

    PropertiesListerHelper.cs

    using System.Reflection;
    
    static public class PropertiesListerHelper
    {
      static private bool IsProcessing;
    
      static public string GetPropertiesAsText(this object instance)
      {
        if ( IsProcessing )
          return $"<Reentrancy in {instance.GetType().Name}.ToString()>";
        IsProcessing = true;
        try
        {
          string result = "";
          var list = instance.GetType().GetProperties().OrderBy(item => item.Name);
          foreach ( var property in list )
          {
            var value = property.GetValue(instance);
            result += $"{property.Name} = {(value == null ? "<null>" : value)}, ";
          }
          return result.TrimEnd(", ".ToArray());
        }
        catch ( Exception ex )
        {
          return $"<Exception in {instance.GetType().Name}.ToString(): {ex.Message}>";
        }
        finally
        {
          IsProcessing = false;
        }
      }
    }
    

    因此,即使类设计发生变化,该行为仍然有效。

    您可以根据需要调整方法以格式化输出,例如:

    foreach ( var property in list )
    {
      var value = property.GetValue(instance);
      result += $"{property.Name} = {(value == null ? "<null>" : value)}"
              + Environment.NewLine;
    }
    return result.TrimEnd(Environment.NewLine.ToArray());
    

    可能会改进对重入情况的管理,因为它可能会导致例如表单上的堆栈溢出。

    【讨论】:

      【解决方案4】:

      答案中未提及的另一种方法是使用以下 Visual Studio 扩展:https://marketplace.visualstudio.com/items?itemName=DavideLettieri.AutoToString。安装扩展程序后,在类主体中点击 Ctrl + .,将会有额外的Generate ToString() 操作可用。

      【讨论】:

        【解决方案5】:

        我不认为 Visual Studio 具有执行这种开箱即用的代码生成的操作。 但是,您可以使用 Visual Studio 的首选扩展来做到这一点:JetBrains Resharper。

        它具有快速生成 ToString 的操作(以及许多其他功能)。

        https://www.jetbrains.com/help/resharper/Code_Generation__Formatting_Members.html

        【讨论】:

        • 我的直接想法是 ReSharper,但我看不出有什么办法。我不知道生成代码菜单存在...谢谢!
        • Resharper 是上帝派来的 ;)。不带 Resharper 的 Visual Studio 可能不是最好的 IDE,但带 Resharper 的 VS 胜过一切。
        • 是的,多年来一直在使用它。主要工作还在 VS2017 中,2019 年一直在涉足没有 R#,但我已经接近安装点...
        • @JamesThorpe 看看生成比较成员:getHasCode 和 Equals 的生成太棒了。
        • 谢谢!我要试试 Resharper。听起来很棒。
        【解决方案6】:

        默认情况下没有办法做到这一点 - 您在 Eclipse 中看到的是 Eclipse 的一个优点,而不是运行时的内置功能。您可以自己编写 VS 的扩展程序(查看我的评论),也可以使用扩展程序。我知道 Resharper offers the facility,但我必须强调,SO 不是“给我找一个可以做...的图书馆”服务,所以我不以任何方式对 Re# 提供任何认可或推荐

        可能还值得指出:

        1. 您可以在功能强大的文本编辑器中相对轻松地做到这一点
        2. 您可以编写一个小应用程序,在将类复制到剪贴板时生成一个 tostring
        3. 你可以放弃对它的渴望;在 c# 中,我们并没有真正像 java bod 那样广泛使用 ToString(),因为自从它首次发布以来,我们已经在 IDE 中内置了一个很棒的步进调试器。我们很少需要对我们的对象进行字符串化并将它们转储到命令行以随时检查程序对象的状态,因为我们可以暂停它并在 Locals 窗口等中查看它。如果您没有完全掌握速度调试器可以为您做的所有事情,我建议您观看一些视频

        【讨论】:

          【解决方案7】:

          你可以这样做:

           public override string ToString()
           {
               return "First name: " + FirstName + ", Last name: " + LastName;
           }
          

          或者更好的解决方案:

           public override string ToString()
           {
               return nameof(FirstName) + FirstName + ", " nameof(LastName) + LastName;
           }
          

          如有必要,对属性使用强制转换。

          【讨论】:

            猜你喜欢
            • 2010-11-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-13
            • 2016-03-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多