Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.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# - Fatal编程技术网

C# 并不是所有的代码路径都返回一个值-怎么了?

C# 并不是所有的代码路径都返回一个值-怎么了?,c#,C#,我做了一个函数,在我看来,它总是返回一个值,但函数仍然表示 所有代码路径都不返回值 我错过什么了吗 public static bool CheckIfSignatureAlreadySignedByUser(SPSite site, SPWeb web, int RowID) { RevertToAppPool revert = new RevertToAppPool(); try { revert.UseAppPoolIdentity();

我做了一个函数,在我看来,它总是返回一个值,但函数仍然表示

所有代码路径都不返回值

我错过什么了吗

public static bool CheckIfSignatureAlreadySignedByUser(SPSite site, SPWeb web, int RowID)
{
    RevertToAppPool revert = new RevertToAppPool();

    try
    {
        revert.UseAppPoolIdentity();
        string dbConnectionString = site.WebApplication.Properties["dbConnection"].ToString();
        using (dbDWDataContext dataContext = new dbDWDataContext(dbConnectionString))
        {
            var signatures = dataContext.CM_Signatures.Where(c => c.ParagraphID == RowID).ToList();
            if (signatures.Any())
            {
                foreach (var sig in signatures)
                {
                    if (sig.LoginName.ToLower() == web.CurrentUser.LoginName.ToLower())
                    {
                        return false;
                    }
                    else
                        return true;
                }    
            }
            else
            {
                return true;
            }                                    
        }
    }
    catch (Exception error)
    {
        SEPUtilities.WriteErrorToLog("Error in DWUtilities.AddSignature: {0}", error.ToString());
        return false;
    }
    finally
    {
        revert.ReturnToImpersonatingCurrentUser();
    }
}

编译器不知道
签名
总是会产生至少一个结果,因为您以前检查过它:

if (signatures.Any())
{
    foreach (var sig in signatures)
    { ... }

    // problem here.

它要您做的是
返回
foreach
语句之后的任何内容。(值得一提的是,
signatures
可以在
Any
foreach
语句之间更改,因为另一个线程对其进行了修改)。

我猜if-foreach{if-else}的分支分析失败,因为VS现在没有该签名。Any不会进入if。相反,试着去写

public static bool CheckIfSignatureAlreadySignedByUser(SPSite site, SPWeb web, int RowID)
    {
        RevertToAppPool revert = new RevertToAppPool();

        try
        {
            revert.UseAppPoolIdentity();
            string dbConnectionString = site.WebApplication.Properties["dbConnection"].ToString();
            using (dbDWDataContext dataContext = new dbDWDataContext(dbConnectionString))
            {
                var signatures = dataContext.CM_Signatures.Where(c => c.ParagraphID == RowID).ToList();
                if (signatures != null && signatures.Any())
                {
                    foreach (var sig in signatures)
                    {
                        if (sig.LoginName.ToLower() == web.CurrentUser.LoginName.ToLower())
                        {
                            return false;
                        }
                        else
                            return true;
                    }

                }

                return true;                    
            }
        }
        catch (Exception error)
        {
            SEPUtilities.WriteErrorToLog("Error in DWUtilities.AddSignature: {0}", error.ToString());
            return false;
        }
        finally
        {
            revert.ReturnToImpersonatingCurrentUser();
        }

    }

@帕特里克·霍夫曼的答案是正确的

也就是说,我将重构:

if (signatures != null && signatures.Any())
{
    foreach (var sig in signatures)
    {
        if (sig.LoginName.ToLower() == web.CurrentUser.LoginName.ToLower())
        {
            return false;
        }
        else
            return true;
    }    
}
else
{
    return true;
}
致:


其他人已经回答了,但这里有一些额外的信息

我认为您的循环不正确:

var signatures = dataContext.CM_Signatures.Where(c => c.ParagraphID == RowID).ToList();
if (signatures.Any())
{
    foreach (var sig in signatures)
    {
        if (sig.LoginName.ToLower() == web.CurrentUser.LoginName.ToLower())
        {
            return false;
        }
        else
            return true;
    }    
}
else
{
    return true;
}      
foreach
循环将只迭代一次。如果您试图找出是否没有签名与当前用户匹配,那么如果第一个签名匹配,即使后面的签名不匹配,也会失败,因为
返回false
将提前终止循环

也许你真的想这么做:

return !signatures.Any(sig => 
    string.Compare(sig.LoginName, web.CurrentUser.LoginName, StringComparison.OrdinalIgnoreCase) == 0);

但实际上,签名可以改变吗?它是一个函数范围的实例,而不是一个成员变量,不会返回到范围之外。也许静态分析器不能100%确定这一点?确实如此,但是如果
Any
启动一个线程,并在后台修改它会怎么样?编译器不知道这些,你说得对。它超出范围-传递给
Any
扩展方法。好电话<从理论上讲,代码>任何
在清除列表时,即使没有线程,也可能返回true。@Avnershaar Kashtan此外,实例实际上没有函数作用域,只有变量是。该实例在其他地方实例化,通过对
Where
ToList
的外部调用只获得一个引用,因此很可能存在对它的其他引用。您使用
foreach
,然后使用
if-else
,这两个都从方法返回?我想你的钱没用。它没有意义,因为它总是从第一次迭代返回。我同意重构,但请注意它与原始代码不一样!只有在更正OP代码中的错误时,这才是正确的重构。@MatthewWatson是真的,但我假设OP的代码有错误:编写的
Where
子句应该只返回一个元素(或者代码确实错误:no
OrderBy
,然后是一个只接受第一个元素的枚举(哪一个?不知道,因为没有顺序)考虑到…,所以它应该是等效的。是的,我也认为OP的代码有一个bug。似乎一些随机的投票人不同意,所以他对我的答案投了否决票(但似乎认为你的答案是可以的;)无论如何,投赞成票。@downvoter:你能解释一下你认为什么是错的吗?如果有什么不对劲,那么Ken2K的答案也是错的(但你没有投反对票)。我想你可能错过了什么……根本不值得投反对票。所以,这是我的+1来平衡:)@现在,我们看到您确实遗漏了一些内容,因为OP已将Ken的答案标记为正确答案。:)(谢谢你,肯)
return !signatures.Any(sig => 
    string.Compare(sig.LoginName, web.CurrentUser.LoginName, StringComparison.OrdinalIgnoreCase) == 0);