亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何強制 throw 成為語句而不是表達式

如何強制 throw 成為語句而不是表達式

C#
胡說叔叔 2022-07-23 18:04:54
throw關鍵字既可以用作表達式也可以用作語句,這很好。雖然,考慮這些重載public static void M(Action doIt) { /*use doIt*/ }public static void M(Func<int> doIt) { /*use doIt*/ }像這樣調用時M(() => throw new Exception());甚至像這樣(帶有語句 lambda)M(() => { throw new Exception(); });編譯器選擇了 M(Func<>) 重載,表明 throw 在這里被視為一個表達式。我怎樣才能優雅而明確地強制編譯器選擇 M(Action) 重載?一種方法是這樣M(() => { throw new Exception(); return; });但是返回語句的原因似乎并不明顯,并且冒著被下一個開發人員更改的風險,特別是因為 Resharper 警告了無法訪問的代碼。(當然我可以更改方法命名以避免重載,但這不是問題。:-)
查看完整描述

4 回答

?
慕后森

TA貢獻1802條經驗 獲得超5個贊

這與 lambda 是語句 lambda 還是表達式 lambda 無關(正如您將 lambda 從表達式 lambda 更改為語句 lambda 并且行為沒有改變最簡潔地展示的那樣)。

有多種方法可以使 lambda 匹配多個可能的重載。這是特定于較新版本的,但自 C# 1.0 以來已經應用了其他方法(并且自從引入匿名方法以來,需要存在匿名方法的特定處理和由此產生的重載決議消歧)。

確定調用哪個重載的規則在 C# 規范的第 7.5.3.3 節中有詳細說明。具體來說,當參數是匿名方法時,它總是更喜歡委托(或表達式)有返回值的重載,而不是沒有返回值的重載。無論是語句 lambda 還是表達式 lambda,這都是正確的;它適用于任何形式的匿名函數。

因此,您要么需要通過使匿名方法對 a 無效來防止重載匹配Func<int>,要么顯式強制類型為 aAction以便編譯器不會自行消除歧義。


查看完整回答
反對 回復 2022-07-23
?
浮云間

TA貢獻1829條經驗 獲得超4個贊

你可以為 for 添加一個強制轉換Action,盡管它確實有點LISP'y與所有括號:

M((Action)(() => throw new Exception()));

不理想,但如果你想要最大的清晰度:

Action thrw = () => throw new Exception();M(thrw);


查看完整回答
反對 回復 2022-07-23
?
呼喚遠方

TA貢獻1856條經驗 獲得超11個贊

為了添加所有給出的合理答案,這里有一個迷人的不合理的答案:

((Action<Action>)M)(() => throw new Exception());

那個應該任何出現的維護程序員的面條,他們會不理會它??纯茨闶欠衲芘宄鼮槭裁雌鹱饔?。


查看完整回答
反對 回復 2022-07-23
?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

一種可能的方法是使用命名參數:


public static void M(Action action) { /* do stuff */ }


public static void M(Func<int> func) { /* do stuff */ }


public static void Main()

{

    M(action: () => throw new Exception());

}

這可能應該記錄在代碼中,以免讓下一個開發人員感到驚訝,并且如注釋中所述,編寫適當的自動化測試來驗證調用了正確的重載。


查看完整回答
反對 回復 2022-07-23
  • 4 回答
  • 0 關注
  • 142 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號