Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果一次性为空,则默认可枚举?_C#_Performance_Linq - Fatal编程技术网

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
案例可以很容易地单独处理,并且没有问题)

为了知道枚举是否为空,我们需要查看它,即尝试获取第一个元素。因为这会启动枚举的枚举,所以我们需要完成它以避免多次枚举

因为这是需要执行的逻辑,所以底层枚举器需要存在(以便它可以执行该代码,并尝试查看原始的枚举器)。为了使该枚举数存在,必须有一个封装在其中的实际对象:枚举数。因此,使用此逻辑会阻止我们返回
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
案例可以很容易地单独处理,并且没有问题)

为了知道枚举是否为空,我们需要查看它,即尝试获取第一个元素。因为这会启动枚举的枚举,所以我们需要完成它以避免多次枚举

因为这是需要执行的逻辑,所以底层枚举器需要存在(以便它可以执行该代码,并尝试查看原始的枚举器)。为了使该枚举数存在,必须有一个封装在其中的实际对象:枚举数。因此,使用此逻辑会阻止我们返回
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