空传播运算符,输出参数和错误的编译器错误? [英] Null propagation operator, out parameters and false compiler errors?

查看:114
本文介绍了空传播运算符,输出参数和错误的编译器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个类,该类的属性类型为 Dictionary< string,string> ,可能为空。

Let's assume I have a class that has a property of type Dictionary<string,string>, that may be null.

这可以编译,但是对 TryGetValue()的调用可能会在运行时抛出 NullRef 异常:

This compiles but the call to TryGetValue() could throw at a NullRef exception at runtime:

MyClass c = ...;
string val;
if(c.PossiblyNullDictionary.TryGetValue("someKey", out val)) {
    Console.WriteLine(val);
}

因此,我添加了一个空传播运算符来防止空值,但是这不会编译:

So I'm adding a null-propagating operator to guard against nulls, but this doesn't compile:

MyClass c = ...;
string val;
if( c.PossiblyNullDictionary ?. TryGetValue("someKey", out val) ?? false ) {

    Console.WriteLine(val); // use of unassigned local variable

}

是否有实际用途如果 val 将在 if 块内未初始化,还是编译器不能简单地推断出这一点(以及原因)?

Is there an actual use case where val will be uninitialized inside the if block, or can the compiler simply not infer this (and why) ?

更新:解决方法最干净的方法(^)^ H ^ H ^ H ^ H ^ H修复此问题:

Update: The cleanest (?) way to workaround^H^H^H^H^H fix this is:

MyClass c = ...;
string val = null; //POW! initialized.
if( c.PossiblyNullDictionary ?. TryGetValue("someKey", out val) ?? false ) {

    Console.WriteLine(val); // no more compiler error

}


推荐答案

通过将 val 初始化为一个erhm值(例如, String.Empty ),编译器能够用空操作符表示意图并按预期方式运行(通过LINQPad,natch):

By initializing val to a erhm, value (e.g., String.Empty) the compiler is able to grok the intent for the null operators and behaves as expected (via LINQPad, natch):

void Main()
{
    MyClass c = new MyClass();
    string val = string.Empty;
    if (c.PossiblyNullDictionary?.TryGetValue("someKey", out val) ?? false)
    {

        Console.WriteLine(val);

    }
}
public class MyClass {
    public Dictionary<string, string> PossiblyNullDictionary;
}
// Define other methods and classes here

Ed:by'我的意思是,如果编译器允许执行保留当前范围而未初始化 val ,则编译器不能对程序的特性做出重要保证。当评估空运算符时,将调用方法。

Ed: by 'grok the intent' I meant that the compiler can't make important guarantees about the program's characteristics if it allows execution to leave the current scope with val uninitialized. When it evaluates the null operators, the method invocation.

您要使用的用例是:
说,我们用 bool SomeMethod(string s,out v )。假设 SomeMethod 被调用时是顽皮的,它的主体只是 return true; 。编译器将方法调用体视为不透明的(因为它可能并不总是存在于编译器可用/可见的程序集中),因此得出结论,无法证明 val

The use case you ask for is this: Say that instead of TryGetValue, we have bool SomeMethod(string s, out v). Let's say that when invoked, SomeMethod is naughty and simply has a body of return true;. The compiler treats method invocation bodies as opaque (since it may not always be in an assembly available/visible to the compiler), so it concludes that there's no way to prove that val is ever initialized.

ed:
为了回应某些评论,我想更新我的答案以指出此行为并非特定于 ?? ?。 C#语言功能;您只需使用三元表达式即可复制相同的效果:

ed: In response to some comments, I wanted to update my answer to point out that this behavior isn't specific to the ?? or ?. C# language features; you can reproduce the same effect simply by using a ternary expression:

c.PossiblyNullDictionary == null ? 
    false : 
    c.PossiblyNullDictionary.TryGetValue("someKey", out val) 
 //error: use of possibly uninitialized local variable

这篇关于空传播运算符,输出参数和错误的编译器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆