有在.NET的方式(或某种标准扩展方法)来询问枚举的问题?

例如是当前项枚举中的第一或最后一个项目:

string s = "";

foreach (var person in PeopleListEnumerator) {

  if (PeopleListEnumerator.IsFirstItem) s += "[";

  s += person.ToString();

  if (!PeopleListEnumerator.IsLastItem) s += ",";
  else s += "]";
}
有帮助吗?

解决方案

只是为了乐趣起见,解决不需要急于评估和具有单个本地变量(除了枚举)的一般问题:

static class TaggedEnumerableExtensions
{
    public class TaggedItem<T>
    {
        public TaggedItem(T value, bool isFirst, bool isLast)
        {
            IsFirst = isFirst;
            IsLast = isLast;
            Value = value;
        }
        public T Value { get; private set; }
        public bool IsFirst { get; private set; }
        public bool IsLast { get; private set; }
    }
    public static IEnumerable<TaggedItem<T>> ToTaggedEnumerable<T>(this IEnumerable<T> e)
    {
        using (var enumerator = e.GetEnumerator()) {
            if (!enumerator.MoveNext())
                yield break;
            var current = enumerator.Current;
            if (!enumerator.MoveNext()) {
                yield return new TaggedItem<T>(current, true, true);
                yield break;
            } else {
                yield return new TaggedItem<T>(current, true, false);
            }

            for (;;) {
                current = enumerator.Current;
                if (!enumerator.MoveNext()) {
                    yield return new TaggedItem<T>(current, false, true);
                    yield break;
                }
                yield return new TaggedItem<T>(current, false, false);
            }
        }
    }
}

测试:

class Program
{
    static void Main(string[] args)
    {
        foreach (var item in Enumerable.Range(0, 10).ToTaggedEnumerable()) {
            Console.WriteLine("{0} {1} {2}", item.IsFirst, item.IsLast, item.Value);
        }
    }
}

其他提示

如果您的收藏是一个列表,你可以这样做:

string s = "[" + String.Join(",", PeopleList.ToArray()) + "]";

不,我知道的。您可以尝试自己编写这样的扩展方法,虽然。或其他地方保持第一/最后一个项目的跟踪。

埃里克利珀有博客文章有关这类问题最近与有关如何修改您的问题描述的一些想法以及更准确地反映你真正想要的东西。

您很可能关闭使用的string.join 更好在这种情况下,一些LINQ:

String.Join(
  ",",
  (from p in PeopleListEnumerator
  select p.ToString()).ToArray()
)

IEnumerable接口不定义或期望,它返回到在任何给定的顺序的项目。因此,“第一”的理念并不总是适用。

然而,对于此特定图案这是我做

StringBuilder result = new StringBuilder();
result.Append( '[' );

foreach( var person in PeopleListEnumerator )
{
    if( result.Length > 1 )
        result.Append( ',' );
    result.Append( person.ToString() );
}

result.Append( ']' );

乔恩斯基特写智能枚举提供这种功能和它们在 MiscUtils 库的一部分。

这是说你的具体例子最好用的string.join()方法解决了许多其他人指出。写一个一般string Join(this IEnumerable<T>,string)扩展是不硬,并且然后在任何更多的情况下可使用的,而不必诉诸于恼人的临时数组。

使用LINQ,你可以这样做:

string s = 
    string.Format("[{0}]", string.Join(",",PeopleListEnumerator.Select(p => p.ToString()).ToArray()));

我发现自己定义和使用了“布尔第一”局部变量,例如:

string s = "[";
bool first = true;

foreach (var person in PeopleListEnumerator) {

  if (first)
    first = false;
  else
    s += ",";
  s += person.ToString();
}
s += "]";

此代码紧密匹配你真的想完成的任务:

StringBuilder s = new StringBuilder("[");
string delimiter = "";

foreach (var person in PeopleListEnumerator) {  
  s.Append(delimiter).Append(person.ToString());
  delimiter = ",";
}

return s.Append("]").ToString();

我皮肤这只猫的方式(是的,有很多方式)是:

StringBuilder sb = new StringBuilder();

foreach (var person in PeopleListEnumerator )
{
    sb.AppendFormat(",{0}", person.ToString());
}

string s = "[" + sb.ToString().Substring(1) + "]";

希望这有助于...

在.NET枚举没有的顺序的概念,除由值。如果你想在第一和最后一个枚举我建议明确界定什么这些第一和最后一个值。下列枚举是一个这样的示例:

public enum PlayerType : byte
{
    Starter = byte.MinValue,
    RegularPlayer = 1,
    BenchWarmer = 2,
    Closer = byte.MaxValue
}

然后,您可以表达类似如下的内容:

List<byte> values = new List<byte>((byte[])Enum.GetValues(typeof(PlayerType)));

PlayerType starter = (PlayerType)values.Min();
PlayerType closer = (PlayerType)values.Max();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top