C# 是否使用.DefaultIfEmpty()而不是.FirstOrDefault()??字符串。空;
我如何集成C# 是否使用.DefaultIfEmpty()而不是.FirstOrDefault()??字符串。空;,c#,linq,C#,Linq,我如何集成.DefaultIfEmpty()扩展方法,以便使用而不是 .FirstOrDefault() ?? String.Empty; 代码: 您可以使用: var query = ...; return query.DefaultIfEmpty(string.Empty).First(); 但这并不能降低IMO的复杂性。如果您对扩展方法感兴趣,那么您可以使用以下方法: public static class Helpers { public static string Fir
.DefaultIfEmpty()
扩展方法,以便使用而不是
.FirstOrDefault() ?? String.Empty;
代码:
您可以使用:
var query = ...;
return query.DefaultIfEmpty(string.Empty).First();
但这并不能降低IMO的复杂性。如果您对扩展方法感兴趣,那么您可以使用以下方法:
public static class Helpers
{
public static string FirstOrEmpty(this IEnumerable<string> source)
{
return source.FirstOrDefault() ?? string.Empty;
}
}
公共静态类帮助程序
{
公共静态字符串FirstOrEmpty(此IEnumerable源)
{
返回source.FirstOrDefault()??string.Empty;
}
}
编辑
此方法不是通用的,因为这样我们就必须使用default(t)
,它将为我们提供null
而不是string。空的代码:
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();
对于DefaultIfEmpty
和FirstOrDefault
的语义含义的怀疑,以下是从库中反编译的代码:
- 代码
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静态IEnumerable DefaultIfEmpty(此IEnumerable源)
{
返回source.DefaultIfEmpty(默认值(TSource));
}
公共静态IEnumerable DefaultIfEmpty(此IEnumerable源,TSource defaultValue)
{
if(source==null)
{
抛出错误。ArgumentNull(“源”);
}
返回DefaultIfEmptyInterator(源,defaultValue);
}
公共静态TSource优先(此IEnumerable源)
{
if(source==null)
{
抛出错误。ArgumentNull(“源”);
}
IList list=源作为IList;
如果(列表!=null)
{
如果(list.Count>0)
{
返回列表[0];
}
}
其他的
{
使用(IEnumerator enumerator=source.GetEnumerator())
{
if(枚举数.MoveNext())
{
返回枚举数.Current;
}
}
}
抛出错误。NoElements();
}
公共静态TSource FirstOrDefault(此IEnumerable源)
{
if(source==null)
{
抛出错误。ArgumentNull(“源”);
}
IList list=源作为IList;
如果(列表!=null)
{
如果(list.Count>0)
{
返回列表[0];
}
}
其他的
{
使用(IEnumerator enumerator=source.GetEnumerator())
{
if(枚举数.MoveNext())
{
返回枚举数.Current;
}
}
}
返回默认值(TSource);
}
这里有几点值得一提:
DefaultIfEmpty
有一个无参数重载,它使用default(TSource)
调用参数化重载并返回其结果
无参数的FirstOrDefault
和First
之间唯一的区别是后者在集合为空时抛出
有关更多信息,请参阅MSDN上的
FirstOrDefault
语义表达的first或default
,即所谓的;它不是第一个命名的,也不是null
。在c#中,引用类型的default(T)
为null,但对于非引用类型,则不是。例如,default(int)
为零
关键字default
从未在语义上表示为null。它是默认的
另外,有关更多信息,请参阅MSDN
我发现这门关于PluralSight的课程很有趣,当我看到这个问题时,我记起了它
您可以观看整个过程,但是Map Reduce和选项
策略(尤其是使用DefaultIfEmpty)似乎非常适合您的用例
.NET中的战术设计模式:控制流
作者:佐兰·霍瓦特
就个人而言,我不会DefaultIfEmpty
感兴趣的是可枚举项,而不是标量值。创建您自己的扩展方法,可能也被命名为FirstOrDefault
,它使用T
参数指定为默认值。然后可能T FirstOrEmpty(此IEnumerable源代码)
@Ilya Ivanov,如果它是泛型的,则字符串的默认值仍然为null。但是T FirstOrDefault(此IEnumerable源代码,T默认值)
是可能的。然后,再次使用.FirstOrDefault(string.Empty)
vs..FirstOrDefault()?string.Empty
并没有多大区别。@hvd,我不得不承认这是我的第一个想法,但在那之后,我决定FirstOrEmpty
可以提供更清晰的输出代码。是的,降低复杂性是我的目标之一。到目前为止,你还有什么其他建议吗?嗨,2k先生。现在你实际上是14k!我转到了你的解决方案。它不会用LINQ转换为实体。它将失败:“方法‘第一’只能用作最终的查询操作。请考虑在该实例中使用方法‘FrrStRealDebug’代替。”我最近不得不替换<代码> Debug TimeType()。
,这应该会得到相同的结果。@Triynko在OP的情况下,它可以正常工作,因为这些操作是最终的查询操作。如果您尝试在子查询中使用它们,则会出现异常。对于这个问题,当序列没有结果时,所需的输出是空字符串-而不是null,因此ken2k的答案是正确的。您的第一个问题是OrDefault();结尾没有意义。如果您期望OrDefault为空值,则序列为空。然后将返回“”,我建议是。First()相反。@Elisa:是的,它们在这里是一样的,因为我只是从你的代码中复制而没有更改,但我认为这并不重要。这很重要。使用FirstOrDefault只有50%的正确率。OrDefault(空值)永远不会发生,并且给读者一个错误的印象,代码在做什么。当然,空值只是“OrDefault”/非值类型(如integer)的默认值。感谢您的修订。1票赞成。以上注释的更正:“…非值类型(如integer)的默认值”。
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);
}