【问题标题】:C# linq FirstOrDefault()C# linq FirstOrDefault()
【发布时间】:2010-10-07 04:30:40
【问题描述】:

我从 IEnumerable 中选择一个双精度值,我如何重载 FirstOrDefault() 函数,以默认返回 null,而不是零,我想要类似:

double? x = from ... .FirstOrDefault();

我现在可以捕获异常,并写入双倍? x = null,但我有 20 个变量,不是这样的

【问题讨论】:

    标签: c# linq overloading


    【解决方案1】:

    不要捕获异常。异常的目的是告诉你你有一个错误,而不是充当控制流。

    编写你自己的扩展方法来做你想做的事情是很简单的,那就这样做吧:

    public static double? FirstOrNull(this IEnumerable<double> items)
    {
        foreach(double item in items)
            return item;
        return null;
    } 
    

    或者,如果你想更喜欢它:

    public static T? FirstOrNull<T>(this IEnumerable<T> items) where T : struct
    {
        foreach(T item in items)
            return item;
        return null;
    } 
    

    有意义吗?

    【讨论】:

      【解决方案2】:

      为什么不直接做:

      double? x = myDoubles.Cast<double?>().FirstOrDefault();
      

      【讨论】:

        【解决方案3】:

        您可以编写以下扩展方法, 我刚刚使用 Reflector 翻录了 FirstOrDefault 方法的代码并进行了修改以满足您的要求。

        public static class MyExtension
        {
            public static TSource? NullOrFirst<TSource>(this IEnumerable<TSource> source) where TSource : struct
            {
                if (source == null)
                {
                    throw new ArgumentNullException("source");
                }
                IList<TSource> list = source as IList<TSource>;
                if (list != null)
                {
                    if (list.Count > 0)
                    {
                        return list[0];
                    }
                }
                else
                {
                    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
                    {
                        if (enumerator.MoveNext())
                        {
                            return enumerator.Current;
                        }
                    }
                }
                return null;
            }
        }
        

        【讨论】:

          【解决方案4】:

          我不知道您使用什么类型的查询。但如果您使用 IEnumerable,您可以尝试以下代码:

          double? x = (/*Some IEnumerable here*/).OfType<double?>().FirstOrDefault();
          

          但如果您关心性能,您最好使用扩展方法。

          【讨论】:

          • 你真的尝试过这个双打序列吗?发生了什么?
          • 当然,我使用 List 进行了尝试,结果完全符合预期,即空列表为 null,否则为第一个值。
          【解决方案5】:

          如果我理解正确,您可以创建一个扩展方法来满足您的特定目的。

          这将允许您使用语法:

          double? d = ( linq expression ).MyCustomFirstOrNull();
          

          http://msdn.microsoft.com/en-us/library/bb383977.aspx

          有关扩展方法的一般语法,另请参阅此示例:

          using System.Linq;
          using System.Text;
          using System;
          
          namespace CustomExtensions
          {
              //Extension methods must be defined in a static class
              public static class StringExtension
              {
                  // This is the extension method.
                  // The first parameter takes the "this" modifier
                  // and specifies the type for which the method is defined.
                  public static int WordCount(this String str)
                  {
                      return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
                  }
              }
          }
          namespace Extension_Methods_Simple
          {
              //Import the extension method namespace.
              using CustomExtensions;
              class Program
              {
                  static void Main(string[] args)
                  {
                      string s = "The quick brown fox jumped over the lazy dog.";
                      //  Call the method as if it were an 
                      //  instance method on the type. Note that the first
                      //  parameter is not specified by the calling code.
                      int i = s.WordCount();
                      System.Console.WriteLine("Word count of s is {0}", i);
                  }
              }
          }
          

          http://msdn.microsoft.com/en-us/library/bb311042.aspx

          【讨论】:

          • 你能不能提供链接,我可以在哪里阅读扩展,我不知道关于 linq 的任何信息
          • @eba - 您询问了如何“重载” FirstOrDefault 方法。这是通过 .Net 中的扩展方法完成的,并且不限于 Linq。 Eric 为您的具体情况提供了一个很好的例子。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-09-03
          • 1970-01-01
          • 2011-01-10
          • 1970-01-01
          • 1970-01-01
          • 2020-01-19
          • 2016-03-20
          相关资源
          最近更新 更多