SingleOrDefault() throws an exception on more than one element

后端 未结 7 1906
野性不改
野性不改 2021-02-05 12:17

I\'m getting an exception whenever I fetch like this

Feature f = o.Features.SingleOrDefault(e => e.LinkName == PageLink);

because this can r

7条回答
  •  北恋
    北恋 (楼主)
    2021-02-05 12:44

    I've found I need the behavior of returning a default value if there is not exactly one element (i.e. zero, two, or more) more often than I need the normal SingleOrDefault behavior, so here's my adapted version of Pieter van Ginkel's answer:

    public static class LinqExtensions
    {
        /// 
        /// Returns the only element of a sequence, or a default value if the sequence is empty or contains more than one element.
        /// 
        public static TSource SingleOrDefaultIfMultiple(this IEnumerable source)
        {
            var elements = source.Take(2).ToArray();
    
            return (elements.Length == 1) ? elements[0] : default(TSource);
        }
    
        /// 
        /// Returns the only element of a sequence, or a default value if the sequence is empty or contains more than one element.
        /// 
        public static TSource SingleOrDefaultIfMultiple(this IEnumerable source, Func predicate)
        {
            return source.Where(predicate).SingleOrDefaultIfMultiple();
        }
    
        /// 
        /// Returns the only element of a sequence, or a default value if the sequence is empty or contains more than one element.
        /// 
        public static TSource SingleOrDefaultIfMultiple(this IQueryable source)
        {
            var elements = source.Take(2).ToArray();
    
            return (elements.Length == 1) ? elements[0] : default(TSource);
        }
    
        /// 
        /// Returns the only element of a sequence, or a default value if the sequence is empty or contains more than one element.
        /// 
        public static TSource SingleOrDefaultIfMultiple(this IQueryable source, Expression> predicate)
        {
            return source.Where(predicate).SingleOrDefaultIfMultiple();
        }
    }
    

    I've omitted the null argument checks because I'm OK with relying on the Take and Where calls to throw exceptions when the arguments are null, but you might feel otherwise.

提交回复
热议问题