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

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

我應該假設每個擁有的實例都實現 IDisposable 嗎?

我應該假設每個擁有的實例都實現 IDisposable 嗎?

C#
慕尼黑5688855 2021-10-09 10:41:35
我正在開發我的小游戲項目,作為學習和練習 C# 的一種方式,但我遇到了一個設計問題。假設我們有以下一組類:interface IGameState{    //Updates the state and returns next active state    //(Probably itself or a new one)    IGameState Tick();}class Game{    public Game(IGameState initialState)    {        activeState = initialState;    }    public void Tick()    {        activeState = activeState.Tick();    }    IGameState activeState;}Game 基本上是 GameStates 的狀態機。我們可以有MainMenuState,LoadingState或SinglePlayingState。但是添加MultiplayerState(代表玩多人游戲)需要一個套接字連接到服務器:class MultiplayerState : IGameState, IDisposable{    public IGameState Tick()    {        //Game logic...        //Communicate with the server using the Socket        //Game logic...        //Render the game        return this;//Or something else if the player quits    }    public void Dispose()    {        server.Dispose();    }    //Long-living, cannot be in method-scope    Socket server;//Or similar network resource}好吧,這是我的問題,我無法將它傳遞給它,Game因為它不知道它應該處理它,并且調用代碼無法輕易知道游戲何時不再需要它。這個類設計幾乎就是我到目前為止所實現的,我可以添加IDisposable,IGameState但我認為它不是一個好的設計選擇,畢竟不是所有IGameState的都有資源。此外,這個狀態機在某種意義上是動態的,任何活動IGameState都可以返回新狀態。所以Game真的不知道哪些是一次性的,哪些是一次性的,所以它只需要測試一切。所以這讓我問了幾個問題:如果我有一個類對非密封類型的參數(例如initialState在游戲的 ctor 中)聲明所有權,我應該總是假設它可以IDisposable嗎?(可能不是)如果我有一個IDisposable實例,我是否應該通過強制轉換到一個沒有實現的基礎來放棄它的所有權IDisposable?(可能沒有)我從中收集到,IDisposable感覺像是一個非常獨特的界面,具有顯著的有損(*) 語義 - 它關心自己的生命周期。這似乎與提供有保證但非確定性內存管理的 GC 本身的想法直接沖突。我來自 C++ 背景,所以真的感覺它試圖實現 RAII 概念,但是一旦有 0 個引用,就會手動調用 Dispose(destructor)。我并不是說這是對 C# 的咆哮,更像是我錯過了某些語言功能?或者也許是 C# 特定的模式?我知道有,using但這只是方法范圍。接下來是終結器,它可以確保調用 Dispose 但仍然不確定,還有其他的嗎?也許像 C++' 這樣的自動引用計數shared_ptr?正如我所說,上面的例子可以通過不同的設計解決(但我認為不應該),但沒有回答可能不可能的情況,所以請不要過多關注它。理想情況下,我希望看到解決類似問題的一般模式。(*) 對不起,也許不是一個好詞。但我的意思是,很多接口都表達了一種行為,如果類實現了所述接口,它只會說“嘿,我也可以做這些事情,但如果你忽略我的那部分,我仍然可以正常工作”。遺忘IDisposable不是無損的。我發現以下問題表明 IDisposable 通過組合傳播,或者它可以通過繼承傳播。這對我來說似乎是正確的,需要更多的輸入,但是可以。也正是這樣MultiplayerState被感染了。但是在我的Game課堂示例中,它也想向上游傳播,這感覺不對。最后一個問題可能是是否應該有任何有損接口,比如它是否是適合這項工作的工具,在這種情況下是什么?或者我知道還有其他常用的有損接口嗎?
查看完整描述

1 回答

?
MYYA

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

你所有的問題都是有效的討論;但是,IDisposable如果您將它傳遞給一個類型,那么當您處于未知狀態時,不知道該類型是否會正確處理它。因此,作為一項規則,一次性類型的原始所有者/初始化程序應始終負責處理。


所以在你的情況下,實例化的人MultiplayerState也負責處理它。如果您必須實例化它,然后將它傳遞給GameState并稍后處理它,那么MultiplayerState應該要求的原始所有者以某種方式跟蹤它并正確處理它。


另外,在實現時,IDisposable我強烈建議將 disposing 添加到類的析構函數中。這是一個故障安全,以防一次性類型沒有正確處理或正確實施。


例子:


 public void Dispose()

 {

      server.Dispose();

      GC.SuppressFinalize(this);

 }


 ~MultiplayerState() => Dispose()

我講這個更在這里,如果你有興趣。


查看完整回答
反對 回復 2021-10-09
  • 1 回答
  • 0 關注
  • 196 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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