簡體   English   中英

來自'??'的C#類型推斷(“var”)賦值null-coalescing運算符

[英]C# type inference (“var”) assignment from '??' null-coalescing operator

我已經閱讀了關於空合並的許多SO問題?? 運算符但它們似乎都沒有解決以下特定問題,它既不涉及可空性此處 ), 運算符優先級此處此處 ),也不涉及隱式轉換此處此處此處此處 )。 我也閱讀了.NET文檔 (更多這里 )並嘗試閱讀官方規范 ,但遺憾的是都無濟於事。


所以這里。 以下兩行之間的唯一區別是在第二行中使用var作為類型推斷,而在第一行中使用顯式類型Random ,而第二行則給出如圖所示的錯誤,而第一行則很好。

Random x = new Random() ?? (x = new Random());        // ok

var    y = new Random() ?? (y = new Random());        // CS0841
                        //  ^-------- error here

CS0841:在聲明之前不能使用局部變量'y'

第二條線是什么讓結果不確定?

從我上面提到的hubub,我了解到左側的可能性?? operator為null引入了對其右側的實際實例化類型的運行時確定的依賴性。 嗯,好吧,我想,......這意味着什么? 也許警報的數量一般都在飄盪?? 這個網站上的運營商應該是某種可怕的警告......

現在歸零,我認為var關鍵字的整個要點(與dynamic非常特別相反)是, 根據定義 ,它不像運行時那樣容易受到影響

換句話說,即使我們采取“永不窺視超越任何分配保守的,但完全站得住腳規則=運算符”,這樣,我們因此與的右側任何沒有得到有用的信息?? ,然后單獨基於左側,整體結果必須 “兼容” Random 也就是說,結果必須是Random或更具體的(派生的)類型; 它不能更一般。 因此,根據定義,不應該將Random作為推斷類型,因為這個編譯時使用var

據我所知,用運行時考慮因素破壞var使其失敗。 這不正是dynamic的意義嗎? 所以我猜問題是:

  • 對於我對C#靜態(即編譯時)打字哲學的理解, null-coalescing運算符是一個單獨的和/或罕見的例外嗎?
  • 如果是,那么這個設計與這里似乎正在發生的事情之間的好處或權衡是什么,即故意將非確定性引入靜態類型推理系統,以及之前沒有表現出來的? 如果不破壞靜態類型的純度, dynamic是否已經實現?
  • 通過對開發人員的可操作反饋來實現編譯時設計的嚴謹性不是強類型的要點之一嗎? 為什么var不能保持嚴格保守主義的策略 - 總是推斷出可以靜態推斷的最具體的類型 - 同時空歸合運算符根據來自的信息做任何想做的事情。未來?

這不是運行時考慮因素。

使用var聲明的變量的編譯時類型是其初始化程序的靜態類型。 靜態類型?? expression是兩個操作數的靜態類型的常見類型。 但是第二個操作數的靜態類型是y的靜態類型,這是未知的。 因此,整個初始化程序的靜態類型是未知的,並且扣除失敗。

確實存在初始化一致的類型,但是使用C#推理規則無法找到它們。

使用var ,類型在編譯時計算出來。 因此,當你寫這個:

var    y = new Random() ?? (y = new Random()); 

編譯器無法確定編譯時y的類型是什么,因此開始大喊大叫 - 決定是否左側?? 是否為null,將在運行時確定。

一個更好的例子是:

public interface IA { void Do(); }
public class A : IA { ... }
public class B : IA { ... }

A a = null;
var something = a ?? new B(); 

應該是什么類型的somethingIAA還是B

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM