【问题标题】:Is there a nicer/inline way of accomplishing the following in C# / LINQ?在 C# / LINQ 中是否有更好的/内联方式来完成以下任务?
【发布时间】:2009-02-11 11:48:04
【问题描述】:

我经常发现自己在 ASP.NET 中继器中填充了需要根据索引设置 CSS 类的项目:“first”用于索引 0,“last”用于索引 (length-1),“mid”在中间:

_repeater.DataSource = from f in foos
                       select new
                       {
                         ...,
                         CssClass = MakeCssClass( foos, f )
                       };


private static string MakeCssClass( Foo[] foos, Foo f )
{
  var index = Array.IndexOf( foos, f );

  if( index == 0 )
  {
    return "first";
  }
  else if( index == foos.Length - 1 )
  {
    return "last";
  }
  else
  {
    return "mid";
  }
}

有没有更好的方法可以实现这一点(例如使用 lambda 函数)?如果我尝试得到 CS0828,“无法将 lambda 表达式分配给匿名类型属性”。

【问题讨论】:

    标签: c# linq lambda


    【解决方案1】:

    您可能对我的SmartEnumerable 感兴趣,请输入MiscUtil

    从使用页面,有一个例子:

    using System;
    using System.Collections.Generic;
    
    using MiscUtil.Collections;
    
    class Example
    {
        static void Main(string[] args)
        {
            List<string> list = new List<string>();
            list.Add("a");
            list.Add("b");
            list.Add("c");
            list.Add("d");
            list.Add("e");
    
            foreach (SmartEnumerable<string>.Entry entry in
                     new SmartEnumerable<string>(list))
            {
                Console.WriteLine ("{0,-7} {1} ({2}) {3}",
                                   entry.IsLast  ? "Last ->" : "",
                                   entry.Value,
                                   entry.Index,
                                   entry.IsFirst ? "<- First" : "");
            }
        }
    }
    

    使用隐式类型变量和更多类型推断,可以很容易地整理语法。我必须花一些时间来解决这个问题,但基础知识已经有了。

    【讨论】:

    • 可爱,谢谢。我向 SmartEnumerable.Entry 添加了一个辅助方法: public V FirstMidLast( V first, V mid, V last ) { if( IsFirst ) { return first; } else if( IsLast ) { 最后返回; } 其他 { 返回中间; } }
    【解决方案2】:

    这是获得这些中频的一种巧妙方法 - 跳过、反转、跳过(这是什么,UNO?)。

    List<SomeClass> myList = foos
      .Select(f => new SomeClass{ ..., CssClass=string.Empty })
      .ToList();
    
    if (myList.Any())
    {        
      myList.First().CssClass = "first";
      myList.Last().CssClass = "last";
      foreach(var z in myList.Skip(1).Reverse().Skip(1))
      {
        z.CssClass = "mid";
      }
    }
    
    _repeater.DataSource = myList;
    

    这里有一个更好的方法来说明这个问题。

    List<SomeClass> myList = foos
      .Select(f => new SomeClass{ ..., CssClass="mid" })
      .ToList();
    
    if (myList.Any())
    {    
      myList.First().CssClass = "first";
      myList.Last().CssClass = "last";
    }
    
    _repeater.DataSource = myList;
    

    当然,如果您使用匿名类型(它们的属性是只读的),这些技术都不会起作用。不要对查询结果使用匿名类型。

    【讨论】:

    • 我更喜欢匿名类型,因为它可以在数据库架构和 ASP.NET 页面之间进行一定程度的编译时检查。
    猜你喜欢
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    相关资源
    最近更新 更多