零繁殖操作员,参数和错误的编译器错误



让我们假设我有一个具有Dictionary<string,string>类型的类,可能为null。

此编译,但对TryGetValue()的呼叫可能会在运行时投掷NullRef例外:

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

因此,我正在添加一个无效的操作员来防止空,但这不会编译:

MyClass c = ...;
string val;
if( c.PossiblyNullDictionary ?. TryGetValue("someKey", out val) ?? false ) {
    Console.WriteLine(val); // use of unassigned local variable
}

是否存在valif块内部未经初始化的实际用例,或者编译器可以根本不推断此(以及为什么)?

更新:最清洁的方法(?)解决方法^h^h^h^h^h^h修复此问题是:

MyClass c = ...;
string val = null; //POW! initialized.
if( c.PossiblyNullDictionary ?. TryGetValue("someKey", out val) ?? false ) {
    Console.WriteLine(val); // no more compiler error
}

似乎您已经遇到了对?.??的编译器理解的限制,这并不令人惊讶,因为它们并没有完全完全融合到该语言中。

如果您没有较新的运营商明确测试,则编译器将同意您的意见:

MyClass c = new MyClass();
string val;
if (c.PossiblyNullDictionary != null && c.PossiblyNullDictionary.TryGetValue("someKey", out val)) {
    Console.WriteLine(val); // now okay
}

通过将val初始化为ERHM,值(例如String.Empty)编译器能够为Null运算符和预期的行为(通过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:通过'grok the Intent'我的意思是,如果编译器允许执行允许执行范围,则可以对程序的特征进行重要保证,以使当前范围与val非初始化。当评估无效操作员时,方法调用。

您要求的用例是:说我们有bool SomeMethod(string s, out v),而不是TryGetValue。假设被调用后,SomeMethod是调皮的,并且只有return true;的主体。编译器将方法调用物体视为不透明的(因为它可能并不总是在编译器可用/可见的组件中),因此可以得出结论,无法证明val曾经是初始化的。

>

ed:在回答一些评论时,我想更新答案,以指出此行为不是???. C#语言功能的特定特定的;您可以简单地使用三元表达来重现相同的效果:

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

那是因为如果C.Pospoblesilenulldictionary为null,则不会执行TryGetValue,并且该表达式不会返回true或false。

c。trygetValue(" somekey",out val)返回无效,您可以用这样的内容替换代码,并会编译:

        string val;
        var result = c.PossiblyNullDictionary?.TryGetValue("key", out val);
        if (result.HasValue && result.Value)
        {
        }

相关内容

  • 没有找到相关文章

最新更新