c# 예제 .FirstOrDefault() 대신.DefaultIfEmpty()를 사용 하시겠습니까 ?? String.Empty;



linq란 (4)

.DefaultIfEmpty() 확장 메서드를 어떻게 통합하여 사용할 수 있습니까?

.FirstOrDefault() ?? String.Empty;

암호:

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


다음을 사용할 수 있습니다.

var query = ...;

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

하지만 이것은 IMO의 복잡성을 줄이지는 못합니다.


코드:

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();

DefaultIfEmptyFirstOrDefault 의 의미 론적 의미에 대한 의문에 대해 라이브러리에서 디 컴파일 된 코드는 다음과 같습니다.

  • 암호

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

여기 언급 할 내용이 있습니다.

  1. DefaultIfEmpty 에는 매개 변수없는 오버로드가 있으며,이 오버로드는 매개 변수화 된 오버로드를 default(TSource) 호출하고 그 결과를 반환합니다.

  2. 매개 변수가없는 FirstOrDefaultFirst 의 유일한 차이점은 컬렉션이 비어있을 때 후자가 throw FirstOrDefault 것입니다.

    자세한 내용은 MSDN의 Enumerable.FirstOrDefault <TSource> 메서드 를 참조하십시오.

  3. FirstOrDefault 의미 론적으로 first or default 표현되며 그렇게 불린다. 그것은 first or null 명명되지 않습니다. C #에서 참조 유형의 default(T)null 이지만 참조 유형이 아닌 경우에는 그렇지 않습니다. 예를 들어, default(int) 는 0입니다.

    키워드 default 는 결코 의미 론적으로 말해지지 않았습니다. DEFAULT 입니다.

    또한 자세한 내용은 MSDN의 기본 키워드 를 참조하십시오.


확장 메소드에 관심이 있다면 다음과 같이 사용할 수 있습니다 :

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

편집하다

이 메소드는 default(T) 을 사용해야하고 string.Empty 대신 null 제공하기 때문에 일반적이지 않습니다.





linq