问题 在编辑器中对枚举项进行排序


有人知道在代码编辑器中对枚举项进行排序的方法,例如使用resharper或其他VS加载项(即按字母顺序或按整数值对项目进行排序)?

在一个项目中,我有一些带有未排序标签的巨大枚举,并且对于对它们进行排序的可读性将是有帮助的。

编辑:只是指出,因为很多人都提到,如果没有明确的值,我完全知道在编译时分配给枚举项的“自动值”。

为了更清楚一点,有两个例子:

public enum Colors
{
/// <summary>
/// Yellow color
///</summary>
Yellow, 
/// <summary>
/// Green color
///</summary>
Green, 
/// <summary>
/// Blue color
///</summary>
Blue,
/// <summary>
/// Red color
///</summary>
Red
}

- >我们可能想按字母顺序重新排序。由于没有明确定义,因此不使用允许的整数值。

另一个例子 :

  public enum Colors
    {
    /// <summary>
    /// Yellow color
    ///</summary>
    Yellow = 3, 
    /// <summary>
    /// Green color
    ///</summary>
    Green = 1, 
    /// <summary>
    /// Blue color
    ///</summary>
    Blue = 2,
    /// <summary>
    /// Red color
    ///</summary>
    Red = 4
    }

- >我们可能想按数字值重新排序,或者,为什么不按字母顺序重新排序。 等等。

而且我还希望在每个条目之前保留注释,这意味着我不能简单地使用Excel或文本编辑器来执行字母排序。

谢谢


13160
2017-08-12 10:03


起源

你的意思是通过Intellisense还是“打印”它们到屏幕或控件?或者你在谈论实际上是否自动使用枚举中的实际项目? - Matt Thomas
我希望Enums每个都明确指定一个值,否则如果你重新排序它们的值会改变 - Dean Chalk
我希望Enums每个都不依赖于特定值,否则如果重新排序它们的值将会改变。 :) - leppie
正如我在问题中指出的那样,我们可能会承认每个项目都有一个明确的值,因此重新排序它们不会影响程序的行为。 - AFract
而另一方面,当然如果没有数字值但只有标签,只有字母排序可能有意义。 - AFract


答案:


为了帮助手动排序,您可以使用Resharper功能来移动成员。

按Ctrl - 转移 - Alt键 - 向上/ 在枚举声明中移动光标周围的值。


4
2017-08-12 13:19



还不是一个完全自动化的解决方案,但很好的捷径谢谢。 - AFract


  1. 选择并剪切枚举值。
  2. 将它们粘贴到Vim中。
  3. :sort
  4. 剪切并粘贴它们。

(养成将尾随逗号添加到最后一个枚举值的习惯是有用的,即使它不是必需的,因为它使重新排序和添加项更容易。)

正如@Dean Chalk指出的那样,重新排序枚举中的项目将影响该项目的基础数量,除非您使用显式编号。只有当您存储这些数字(例如,存储到数据库),使用它们与外部进程通信或将枚举转换为另一个枚举时,它才会影响您。


3
2017-08-12 10:09



当我回答Danny Chen时,如果枚举项包含摘要,则此方法将不起作用。 - AFract
@Richard:在这种情况下,请查看我的新答案,以便于手动排序。 - Paul Ruane


如果您确定他们的重新排序没有带来任何错误,您可以选择所有错误并粘贴到Excel工作表中,右键单击单元格并使用 sort EXCEL的功能,然后将它们复制回VS.


2
2017-08-12 10:22



谢谢你,但是如果enum的项目前面有/// <summary>注释,那么它将不起作用,并且它不能用数值对它们进行排序。 - AFract


这是一个有趣的问题,我也喜欢解决方案,所以我写了一小段实用程序代码来完成这项工作

public static string GetReorderedEnumCode<T>()
{
    var t = typeof (T);
    if (!t.IsEnum)
    {
        throw new ApplicationException("method requires enum as type parameter");
    }
    var sb = new StringBuilder();
    sb.Append(string.Format(@"public enum {0}
{{
", t.Name));
    var names = Enum.GetNames(t);
    var vals = (int[])Enum.GetValues(t);
    Enumerable.Range(0, vals.Length)
                .Select(i => Tuple.Create(names[i], vals[i]))
                .OrderBy(t2 => t2.Item1)
                .ToList()
                .ForEach(r => sb.Append(string.Format("     {0} = {1},",
    r.Item1, r.Item2) + Environment.NewLine));
    return sb.ToString().TrimEnd(',') + "}";
}


public enum TestEnum
{
    FirstValue,
    AnotherValue,
    LastValue
}

var tmp = Utility.GetReorderedEnumCode<TestEnum>();
Debug.Write(tmp);

看看你的调试输出,你会看到你的新代码 - 它不理想,但它给你一个解决方案:)


2
2017-08-12 10:41



有趣的一段代码。但是,因为它运行在已编译的代码上,所以它不会保留摘要;)。而且,需要.Net 4(对于元组)。我正在寻找直接运行到VS的解决方案,就像重构工具一样。我在Refactor中找不到任何东西!或resharper或任何其他加载项。但是,谢谢你花时间写这篇文章。 - AFract


这对我有用:

我复制到记事本++,用过:

Edit -> Line Operators -> Sort command

然后复制回VS.


0
2017-08-15 21:24



抱歉,您的回答完全忽略了每个枚举条目之前的评论。还有关于用数值而不是标签对它们进行排序的担忧。有很多简单的方法可以按字母顺序对文本进行排序,如果答案非常明显,我就不会在SO上发布我的问题,这在问题的最后清楚地解释了...... - AFract


我没有在编辑器(Visual Studio或ReSharper)中找到一个好方法,但是将一个通用的逗号分隔列表复制并粘贴到一个 像这样的网站 并让它排序。


-1
2017-10-23 21:31



就像我之前对Danny Chen说的那样,这不会起作用,因为它会丢失注释,并且不能用于对条目的数值进行排序。我已经编辑了关于此的原始问题。 - AFract