C# 如果一次性为空,则默认可枚举?
您有简单的扩展签名:C# 如果一次性为空,则默认可枚举?,c#,performance,linq,C#,Performance,Linq,您有简单的扩展签名: public static IEnumerable<T> DefaultEnumerableIfEmpty<T>(this IEnumerable<T> enumerable, IEnumerable<T> defaultEnumerable) 公共静态IEnumerable DefaultEnumerableFempty(此IEnumerable可枚举,IEnumerable defaultEnumerable) 如果初
public static IEnumerable<T> DefaultEnumerableIfEmpty<T>(this IEnumerable<T> enumerable, IEnumerable<T> defaultEnumerable)
公共静态IEnumerable DefaultEnumerableFempty(此IEnumerable可枚举,IEnumerable defaultEnumerable)
如果初始集合为null或空,则返回defaultEnumerable。默认可枚举项可以是null、空或非空(换句话说,它可以是您想要的任何值)。
这里有一个问题:如何实现一次运行?这可能吗
我提出了这个解决方案:
public static IEnumerable<T> DefaultEnumerableIfEmpty<T>(this IEnumerable<T> enumerable, IEnumerable<T> defaultEnumerable)
{
if (enumerable != null)
{
var enumer = enumerable.GetEnumerator();
if (enumer.MoveNext())
{
yield return enumer.Current;
while (enumer.MoveNext())
{
yield return enumer.Current;
}
yield break;
}
}
return defaultEnumerable;//of course this will fail to compile
}
公共静态IEnumerable DefaultEnumerableFempty(此IEnumerable可枚举,IEnumerable defaultEnumerable)
{
if(可枚举!=null)
{
var enumer=enumerable.GetEnumerator();
if(枚举器.MoveNext())
{
产生返回枚举器。当前;
while(enumer.MoveNext())
{
产生返回枚举器。当前;
}
屈服断裂;
}
}
返回defaultEnumerable;//当然这将无法编译
}
当然,它将无法编译。所以,这是一个问题。您有以下两个关键要求:
- 不应多次迭代任何可枚举项
- 如果原始可枚举项为null或空,
为defaultEnumerable
,则函数应返回null
(非空可枚举项)null
可枚举的
(null
案例可以很容易地单独处理,并且没有问题)
为了知道枚举是否为空,我们需要查看它,即尝试获取第一个元素。因为这会启动枚举的枚举,所以我们需要完成它以避免多次枚举
因为这是需要执行的逻辑,所以底层枚举器需要存在(以便它可以执行该代码,并尝试查看原始的枚举器)。为了使该枚举数存在,必须有一个封装在其中的实际对象:枚举数。因此,使用此逻辑会阻止我们返回null
唯一可行的方法是尽早执行逻辑。一个简单的解决方案是首先将整个可枚举项读入内存:
public static IEnumerable<T> DefaultEnumerableIfEmpty<T>(this IEnumerable<T> enumerable, IEnumerable<T> defaultEnumerable)
{
if (enumerable == null)
return defaultEnumerable;
List<T> items = enumerable.ToList(); // enumerate it once
if (items.Count == 0)
return defaultEnumerable;
return items;
}
或者,如果接受返回空的枚举表而不是null
,则可以创建一个生成器,尝试迭代该枚举表并从中生成,如果原始枚举表中没有值,则返回默认枚举表。这将始终返回非空的可枚举项,但:
public static IEnumerable<T> DefaultEnumerableIfEmpty<T>(this IEnumerable<T> enumerable, IEnumerable<T> defaultEnumerable)
{
bool didYield = false;
if (enumerable != null)
{
foreach (var item in enumerable)
{
didYield = true;
yield return item;
}
}
if (!didYield && defaultEnumerable != null)
{
foreach (var item in defaultEnumerable)
yield return item;
}
}
公共静态IEnumerable DefaultEnumerableFempty(此IEnumerable可枚举,IEnumerable defaultEnumerable)
{
bool-didYield=false;
if(可枚举!=null)
{
foreach(可枚举中的变量项)
{
didYield=true;
收益回报项目;
}
}
如果(!didYield&&defaultEnumerable!=null)
{
foreach(defaultEnumerable中的var项)
收益回报项目;
}
}
您有以下两个关键要求:
- 不应多次迭代任何可枚举项
- 如果原始可枚举项为null或空,
为defaultEnumerable
,则函数应返回null
(非空可枚举项)null
可枚举的
(null
案例可以很容易地单独处理,并且没有问题)
为了知道枚举是否为空,我们需要查看它,即尝试获取第一个元素。因为这会启动枚举的枚举,所以我们需要完成它以避免多次枚举
因为这是需要执行的逻辑,所以底层枚举器需要存在(以便它可以执行该代码,并尝试查看原始的枚举器)。为了使该枚举数存在,必须有一个封装在其中的实际对象:枚举数。因此,使用此逻辑会阻止我们返回null
唯一可行的方法是尽早执行逻辑。一个简单的解决方案是首先将整个可枚举项读入内存:
public static IEnumerable<T> DefaultEnumerableIfEmpty<T>(this IEnumerable<T> enumerable, IEnumerable<T> defaultEnumerable)
{
if (enumerable == null)
return defaultEnumerable;
List<T> items = enumerable.ToList(); // enumerate it once
if (items.Count == 0)
return defaultEnumerable;
return items;
}
或者,如果接受返回空的枚举表而不是null
,则可以创建一个生成器,尝试迭代该枚举表并从中生成,如果原始枚举表中没有值,则返回默认枚举表。这将始终返回非空的可枚举项,但:
public static IEnumerable<T> DefaultEnumerableIfEmpty<T>(this IEnumerable<T> enumerable, IEnumerable<T> defaultEnumerable)
{
bool didYield = false;
if (enumerable != null)
{
foreach (var item in enumerable)
{
didYield = true;
yield return item;
}
}
if (!didYield && defaultEnumerable != null)
{
foreach (var item in defaultEnumerable)
yield return item;
}
}
公共静态IEnumerable DefaultEnumerableFempty(此IEnumerable可枚举,IEnumerable defaultEnumerable)
{
bool-didYield=false;
if(可枚举!=null)
{
foreach(可枚举中的变量项)
{
didYield=true;
收益回报项目;
}
}
如果(!didYield&&defaultEnumerable!=null)
{
foreach(defaultEnumerable中的var项)
收益回报项目;
}
}
很难从你的代码看出背后的真正意图。你需要添加更多的细节我不知道你还需要什么。这是一个带有孩子气逻辑的简单扩展。将returndefaultEnumerable
更改为foreach(defaultEnumerable中的var项)生成返回项
应该可以完成此操作。不,这不会完成此操作,因为defaultEnumerable可为null。我厌倦了每次都提到它。很难从你的代码中看出它背后的真正意图。你需要添加更多的细节我不知道你还需要什么。这是一个带有孩子气逻辑的简单扩展。将returndefaultEnumerable
更改为foreach(defaultEnumerable中的var项)生成返回项代码>sho