首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用ToString在数组中显示对象类型?

如何使用ToString在数组中显示对象类型?
EN

Stack Overflow用户
提问于 2021-05-16 20:51:23
回答 3查看 76关注 0票数 2

我有一个包含不同类型对象的数组,例如:

代码语言:javascript
复制
Object[] array = {"String_1", double 3.14, "String_2"};

我想覆盖ToString(),这样当我在上面的数组上使用它时,它将显示对象类类型以及它们在数组中的数量,例如:

代码语言:javascript
复制
Object[] array = {"String_1", double 3.14, "String_2"};

Console.WriteLine(array.ToString()); // will print "String-2,Double-1"

我需要一些帮助来做这件事:-)

EN

回答 3

Stack Overflow用户

发布于 2021-05-17 02:42:56

您不能为您不拥有的类编写自己的ToString实现,并且您也不拥有Array类。

您需要编写自己的方法将数组转换为您喜欢的格式。幸运的是,这在LINQ中是非常简单的。我们甚至可以让它成为一种扩展方法,让它看起来更自然

代码语言:javascript
复制
using System.Linq;

public static class ArrayExt
{
   public static string ToCustomString(this object[] array) 
   {
      var grouped = array.GroupBy(
         c => c?.GetType(), 
         (type, vals) => $"{type?.Name ?? "null"}-{vals.Count()}"
      );
      var result = string.Join(",", grouped);
      return result;
   } 
} 

下面是它的用法示例:

代码语言:javascript
复制
object[] array = new object[] { 1, 2, "Three", 4.0f, "Five", 6M }; 
// extension method syntax 
var value1 = array.ToCustomString();
// or static invocation sytanx
var value2 = ToCustomString(array);

SharpLab

这将根据Typenull使用GroupBy对数组中的各个项进行分组。对每个组进行转换,这样我们现在就有了一个集合,其中每一项都是"{TypeNameOrNull}-{Count}"格式的字符串。然后我们将其传递给string.Join以构建一个组合字符串,并用逗号分隔每一项。

如果您知道您的阵列中不会有null,我们可以将上述操作简化为:

代码语言:javascript
复制
var grouped = array.GroupBy(
   c => c.GetType(),
   (type, vals) => $"{type.Name}-{vals.Count()}"
);
var result = string.Join(",", grouped);

例如,如果您想要按每个类型/组的项目数对最终字符串进行排序,则需要一个更详细的版本,将GroupByOrderBySelect相结合

代码语言:javascript
复制
var groupedAndOrdered = array
    .GroupBy(
       c => c.GetType(), 
       (type, vals) => new { Name = type.Name, Count = vals.Count() }
    )
    .OrderBy(c => c.Count)
    .Select(c => $"{c.Name}-{c.Count}");
var result = string.Join(",", groupedAndOrdered);

如果您不喜欢内置的类型名称(用Single代替float,用Int32代替integer),那么您需要编写一个包含将它们转换为首选文本的逻辑的方法:

代码语言:javascript
复制
public static string TypeToName(Type type) {
    if (type == null) return "null";
    if (type == typeof(float)) return "float";
    if (type == typeof(int)) return "int";
    // etc 
    return type.Name; // fallback 
} 

然后,您可以在构造字符串时使用它,例如:

代码语言:javascript
复制
var grouped = array.GroupBy(
   c => c?.GetType(),
   (type, vals) => $"{TypeToName(type)}-{vals.Count()}"
);
var result = string.Join(",", grouped);
票数 2
EN

Stack Overflow用户

发布于 2021-05-16 21:27:18

对于重写,您需要从数组类型派生。但是你甚至不能从数组类型中派生出来。即使您将ToString()设置为扩展方法,默认的ToString()方法也将始终优先于扩展方法。在这里,您唯一的选择是创建一个带有覆盖的ToString()的自定义数组类型。

代码语言:javascript
复制
public class CustomArray
{
    private object[] array;

    public CustomArray(int size) => array = new object[size]; 

    public CustomArray(object[] array) => this.array = array;
    
    public object this[int index] { get => array[index]; set => array[index] = value; } //Indexer 
    
    public override string ToString()
    {
          var dict = new Dictionary<Type, int>();
          foreach (var item in array) 
          {
              Type type = item.GetType();
              if (dict.ContainsKey(type)) 
              {
                  dict[type]++;
              } 
              else
              {
                 dict[type] = 1;  
              }
          }
          return string.Join(", ", dict.Select(item => $"{item.Key.Name}: {item.Value}"));
          
    } 
}

当然,您可以更深入地让您的自定义数组实现IEnumerable<T>ICollection<T>和其他接口(参见this answer),使其与内置数组类型更加一致。

票数 0
EN

Stack Overflow用户

发布于 2021-05-16 23:12:23

为什么需要覆盖ToString

相反,可以编写一个函数来以所需的格式StringfyObjectArrayMap这些值。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67556887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档