2010-06-08 62 views
10

設置初始值是沒有任何缺點像類:C# - 缺點在聲明

class Example1 
{ 
    protected string UserId = (string)Session["user"]; 
} 
//versus 

class Example2 
{ 
    protected string UserId; 
    public Example2() 
    { 
     UserId = (string)Session["user"]; 
    } 
} 

如果我總是要設置這個值有什麼缺點例1?

UPDATE:
會話[ 「用戶」]是在Global.asax在session_start設置。所以如果失敗了。反正什麼都不應該做。

+0

會話初始化了嗎? – ANeves 2010-06-08 14:37:55

+0

更新問題 – BuddyJoe 2010-06-08 14:42:53

+0

我最喜歡使用的合併操作符UserId =(string)Session [「user」]? 「0」; – kenny 2010-06-08 14:46:45

回答

5

你最大的問題是如果這個protected string UserId = (string)Session["user"];失敗。你沒有辦法優雅地退化。通過將其放入構造函數等中,您可以檢查會話並決定要做什麼。

作爲一般規則,我只會嘗試將我知道的值取爲UserId = -1;等,然後在需要時在代碼塊中修改它們。你永遠不知道什麼時候會出錯,你需要從中恢復過來。

2

主要缺點是您只能使用單個語句設置值。例如,如果你想檢查會話密鑰是否存在,如果它沒有,你想給它分配一個值,那麼你不能通過設置初始值來完成。

2

如果檢入調試器,聲明中的值(例1)的設置發生在構造函數被調用之前,因此您需要確保它不依賴於構造函數中設置的任何內容。

+0

好點。我會記得檢查這些情況+1 – BuddyJoe 2010-06-08 19:23:58

1

我強烈建議使用「安全」的演員。

UserId = Session["user"] as string; 

這樣,如果會話項不存在或不是字符串,則不會失敗。你只需得到一個null,你可以在使用UserId之前測試它。

+3

在這種情況下安全鑄造的方式太多了。如果它不是一個字符串,我會想象你可能會想要一個錯誤。你正在編寫代碼到firsat的地方,並且你期待一個字符串,所以如果它不是一個字符串,它應該被提出來作爲一個需要修復的問題。我見過太多的系統表現出奇怪的行爲,因爲錯誤的類型存儲在某個地方,安全的轉換隱藏了真正的錯誤,並且使它看起來像是一個未初始化的變量錯誤。只是我的兩分錢。 – 2010-06-08 14:50:15

+0

他的評論(在您的回答後添加)表明'Session [「user」]'*必須*是一個字符串,所以最好的例外是將問題扼殺在萌芽狀態 – STW 2010-06-08 15:03:03

+0

提出異常應該始終是一種選擇,只要你知道一個例外是可能的。在這種情況下讓異常飛行是正確的,但也可能不是。安全鑄造給你一個選擇。 – 2010-06-08 15:33:56

1

據我所知,有除了在語句的執行,而事實上,你受到很大的侷限在內嵌代碼單行語句的順序直列值初始化和構造方法初始化,並無實質區別。

執行順序是值初始值設定項在任何構造函數邏輯之前以非特定順序執行,因此如果任何初始化語句碰巧有副作用,那麼您可能會遇到一些令人討厭的意外。但是,確保代碼能夠運行,因此稍後不可能添加其他構造函數,並且忘記初始化某些字段。

我更喜歡使用(鏈接)構造函數內聯初始化,因爲我發現代碼更具可讀性這種方式,也我可以做任何額外的檢查可能會變得必要的道路。

0

我使用的指導方針:在編譯時使用字段初始值設定項來獲取已知的基本值。如果您正在查找全局集合或某些非平凡的邏輯,請將其移入ctor(如其他人指出的,用於錯誤處理/恢復)。

假設你確定不會有什麼錯誤,

  • 上攻:字段初始易於閱讀。
  • 缺點:如果你有一堆字段初始化和多個構建函數,爲初始化的IL將在每個男星導致一些IL膨脹上面插入。所以在這種情況下,調用類似Initialize的方法會更好。

除此之外,我沒有看到場初始化器的任何缺點。

0

很難知道如何開始說這不是一個好主意,原因很多。第一次會話必須是全局變量,否則你的代碼甚至不會編譯。我猜你在上下文中的Session是System.Web.HttpContext.Current.Session,所以,你的代碼甚至不會編譯。假設你有Session作爲一個全局變量,那麼你必須正確地初始化它並分配Session [「user」],那麼你將如何去做呢?然後,在類和會話之間創建這種依賴關係,那麼如何進行單元測試?加上其他所有答案的其他原因。

0

您可能有一天想要第二個具有不同UserId值的構造函數。

0

AFAIK構造函數始終在所有字段初始化後調用。因此,在示例2中,首先將字段初始化爲Null,然後再將其初始化爲(string)Session["user"]