C# 使用 .DefaultIfEmpty() 而不是 .FirstOrDefault() ?? String.Empty;

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15781975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:56:13  来源:igfitidea点击:

Use .DefaultIfEmpty() instead of .FirstOrDefault() ?? String.Empty;

c#linq

提问by Elisabeth

How can I integrate the .DefaultIfEmpty()extension method so I have notto use

如何集成.DefaultIfEmpty()扩展方法,以便我不必使用

.FirstOrDefault() ?? String.Empty;

Code:

代码:

(from role in roleList
let roleArray = role.RoleId.Split(new char[] { WorkflowConstants.WorkflowRoleDelimiter })
where roleArray.Length.Equals(_SplittedRoleIdArrayLength) && 
      HasAccessToCurrentUnit(roleArray[_UnitIndexInRoleId])
select roleArray[_LevelIndexInRoleId]).FirstOrDefault() ?? String.Empty;

采纳答案by ken2k

You could use:

你可以使用:

var query = ...;

return query.DefaultIfEmpty(string.Empty).First();

But this doesn't reduce the complexity IMO.

但这并没有降低 IMO 的复杂性。

回答by Denys Denysenko

If you're interested in extension method then you could use something like this:

如果你对扩展方法感兴趣,那么你可以使用这样的东西:

public static class Helpers
{
    public static string FirstOrEmpty(this IEnumerable<string> source)
    {
        return source.FirstOrDefault() ?? string.Empty;
    }
}

Edit

编辑

This method isn't generic because then we'd have to use default(T)and it'll give us nullinstead of string.Empty.

这个方法不是通用的,因为那样我们就必须使用default(T)它,它会给我们null而不是string.Empty.

回答by Ken Kin

The code:

编码:

var query=(
    from role in roleList
    let delimiter=WorkflowConstants.WorkflowRoleDelimiter
    let roleArray=role.RoleId.Split(new char[] { delimiter })
    where roleArray.Length.Equals(_SplittedRoleIdArrayLength)
    where HasAccessToCurrentUnit(roleArray[_UnitIndexInRoleId])
    select roleArray[_LevelIndexInRoleId]
    ).DefaultIfEmpty("").FirstOrDefault();

For the suspicion about the semantic meaning of DefaultIfEmptyand FirstOrDefault, following is the code decompiled from the library:

出于对DefaultIfEmptyand语义的怀疑FirstOrDefault,以下是从库中反编译出来的代码:

  • Code

    public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source)
    {
        return source.DefaultIfEmpty<TSource>(default(TSource));
    }
    
    public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        return DefaultIfEmptyIterator<TSource>(source, defaultValue);
    }
    
    public static TSource First<TSource>(this IEnumerable<TSource> source)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("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;
                }
            }
        }
        throw Error.NoElements();
    }
    
    public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("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 default(TSource);
    }
    
  • 代码

    public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source)
    {
        return source.DefaultIfEmpty<TSource>(default(TSource));
    }
    
    public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        return DefaultIfEmptyIterator<TSource>(source, defaultValue);
    }
    
    public static TSource First<TSource>(this IEnumerable<TSource> source)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("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;
                }
            }
        }
        throw Error.NoElements();
    }
    
    public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("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 default(TSource);
    }
    

And here are something to mention:

这里有一些值得一提的:

  1. DefaultIfEmptyhas a parameterless overload, which invokes the parameterized overload with default(TSource)and return its result.

  2. The only difference between parameterless FirstOrDefaultand First, is the latter would throw when the collection is empty.

    For more information, see Enumerable.FirstOrDefault<TSource> Methodon MSDN.

  3. FirstOrDefaultsemantically expressed first or default, and so called; it's not named first or null. In c#, default(T)for a reference type is null, but for non-reference type, it's not. For example, default(int)is zero.

    The keyword defaultwas never said nullsemantically. It's DEFAULT.

    Also, for more information, default Keywordon MSDN.

  1. DefaultIfEmpty有一个无参数重载,它调用参数化重载default(TSource)并返回其结果。

  2. 无参数FirstOrDefaultFirst,之间的唯一区别是后者会在集合为空时抛出。

    有关详细信息,请参阅MSDN 上的Enumerable.FirstOrDefault<TSource> 方法

  3. FirstOrDefault语义上表达的first or default,所谓的;它没有命名first or null。在 c# 中,default(T)对于引用类型是null,但对于非引用类型,它不是。例如,default(int)为零。

    关键字default在语义上从未被说为。这是默认的

    此外,有关更多信息,请参阅MSDN 上的默认关键字

回答by Ian Robertson

I found this course on PluralSight interesting and I remembered it when I saw this question.

我发现 PluralSight 上的这门课程很有趣,当我看到这个问题时我就记住了。

You could watch the whole course, but the Map Reduce and Option<T>strategies especially with DefaultIfEmpty seemed like it could be a good fit to your use case.

您可以观看整个课程,但 Map Reduce 和Option<T>策略,尤其是 DefaultIfEmpty 似乎很适合您的用例。

Tactical Design Patterns in .NET: Control Flow by Zoran Horvathttps://app.pluralsight.com/library/courses/tactical-design-patterns-dot-net-control-flow/table-of-contents

.NET 中的战术设计模式:Zoran Horvat 的控制流https://app.pluralsight.com/library/courses/tactical-design-patterns-dot-net-control-flow/table-of-contents