C# 用于空检查的ReSharper ContractAnnotation+;给出反直观结果的Out变量

C# 用于空检查的ReSharper ContractAnnotation+;给出反直观结果的Out变量,c#,resharper,jetbrains-ide,rider,C#,Resharper,Jetbrains Ide,Rider,我有一个相对简单的扩展方法,叫做TryGetFirst public static bool TryGetFirst<T>(this IList<T> list, out T value) { if (list == null || list.Count == 0) { value = default; return false; } value = list[0]; return true; }

我有一个相对简单的扩展方法,叫做TryGetFirst

public static bool TryGetFirst<T>(this IList<T> list, out T value)
{
    if (list == null || list.Count == 0)
    {
        value = default;
        return false;
    }

    value = list[0];
    return true;
}
publicstaticbooltrygetfirst(此IList列表,out T值)
{
if(list==null | | list.Count==0)
{
值=默认值;
返回false;
}
值=列表[0];
返回true;
}
它可以同时做一些事情。它null检查列表,检查列表是否为空,如果为空,则返回第一个元素。有点像Linq的FirstOrDefault,但是有一个内置的空检查。不要太花哨

我正在寻找正确的ContractAnnotation语法,以便将以下事实传达给ReSharper,但我似乎无法将它们全部确定下来

  • 如果列表为null,则始终返回false
  • 如果返回值为true,则列表不为null
  • 如果返回值为false,则该值为null
  • 给出下面的代码,我期望得到下面的ReSharper提示,至少在Rider中的悲观值分析模式下是这样

    if (StringExtensions.TryGetFirst<object>(null, out object value) { ... } // Expression is Always False
    
    if (_possiblyNullList.TryGetFirst<object>(out object value)
    {
        _possiblyNullList.DoSomething(); // No Warning
        value.DoSomething(); // Possible NullReferenceException
    }
    else
    {
        _possiblyNullList.DoSomething(); //Possible NullReferenceException
        if (value == null) { ... } // Expression is Always True
    }
    
    if(StringExtensions.TryGetFirst(null,out对象值){…}//表达式始终为False
    if(_possiblyNullList.TryGetFirst(输出对象值)
    {
    _possiblyNullList.DoSomething();//无警告
    value.DoSomething();//可能的NullReferenceException
    }
    其他的
    {
    _possiblyNullList.DoSomething();//可能的NullReferenceException
    如果(value==null){…}//表达式始终为True
    }
    
    起初,我尝试了
    [ContractAnnotation(“list:null=>false;=>false,value:null”)]
    ,但由于某种原因,ReSharper解释为所有代码路径都返回false,因此如果{…}无法访问
    的内容

    接下来,我尝试了
    [ContractAnnotation(“list:null=>false;=>false,value:null;=>true”)]
    ,因为我认为在末尾添加true大小写会通知ReSharper可能会得到一个true结果。这稍微好一点,但是
    \u possiblyNullList.DoSomething()
    在if块内被标记为可能的null引用,并且
    StringExtensions.TryGetFirst(null,
    不再被标记为始终为False

    最接近我的目标是
    [ContractAnnotation(=>true,list:notnull,value:canbenull;=>false,list:canbenull,value:null”)]
    它处理除
    StringExtensions.TryGetFirst之外的所有情况(null,
    不会被标记为始终为False。我尝试添加回
    列表:null=>False
    行,但没有任何区别。我也觉得这种语法比看起来需要的要详细得多,但如果它是准确的,我愿意接受它

    我觉得我的排列已经用完了。这只是一个属性不支持的情况,还是我遗漏了一些明显的东西?

    试试这个:
    list:null=>false,value:null;list:notnull=>false,value:null;list:notnull=>true,value:canbenull

    似乎
    [ContractAnnotation(“list:null=>false,value:null”)]
    起到了作用。至少在指定的要求下。@GuruStron另一个非常接近的,但至少在我看来它没有标记
    如果(value==null){…}
    在else块中始终为true。在某些情况下,list不为null,但返回值为false,因此out值为null。