C # linq FirstOrDefault () - PullRequest
       4

C # linq FirstOrDefault ()

3 голосов
/ 07 октября 2010

Я выбираю одно двойное значение из IEnumerable, как я могу перегрузить функцию FirstOrDefault (), чтобы вернуть ноль по умолчанию, а не ноль, что-то вроде:

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

я теперь могу ловить исключениеа пишешь попутно?х = ноль, но у меня есть 20 переменных, и это не так

Ответы [ 5 ]

16 голосов
/ 07 октября 2010

Не поймите исключение. Цель исключения - сообщить вам, что у вас есть ошибка, а не действовать как поток управления.

Довольно просто написать собственный метод расширения, который делает то, что вы хотите, поэтому сделайте это:

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;
} 

Имеет смысл?

10 голосов
/ 07 октября 2010

Почему бы просто не сделать:

double? x = myDoubles.Cast<double?>().FirstOrDefault();
5 голосов
/ 07 октября 2010

Вы можете написать следующий метод расширения, Я только что скопировал метод Code of FirstOrDefault с помощью Reflector и исправил его в соответствии с вашими требованиями.

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;
    }
}
1 голос
/ 07 октября 2010

Я не знаю, какие типы запросов вы используете.Но если вы работаете с IEnumerable, вы можете попробовать следующий код:

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

Но если вы заботитесь о производительности, вам лучше использовать методы расширения.

1 голос
/ 07 октября 2010

Если я правильно понимаю, вы можете создать метод расширения, соответствующий вашим конкретным целям.

Это позволит вам использовать синтаксис:

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

...