2017-01-25 96 views
1

我很困惑下面的代碼和使用語句及其對象處置的範圍。使用語句內部成員的範圍

using(DbFactory db = new DbFactory()) 
{ 
    Repository repo = new Repository<someobject>(db); 
    result = repo.Get(somecondition); 
} 

在這段代碼的使用塊執行後會發生什麼將DbFactory得到處理?
在using語句中使用的變量的範圍是repo
DbFactoryRepository使用,它有一個成員變量,它將容納DbFactory。 那麼這會持有DbFactory的處置嗎?

EDIT1:

Repository repo; 
ResultObject result; 
using(DbFactory db = new DbFactory()) 
{ 
    repo = new Repository<someobject>(db); 
    result = repo.Get(somecondition); 
} 

public class Repository 
{ 
    private _dbFactory; 

    public Repository(DbFactory dbFactory) 
    { 
     _dbFactory = dbFactory; 
    } 
} 

現在將DbFactory被設置在使用後聲明?

回答

8

repo變量的範圍(在第一種情況下)是using聲明。你不能在using聲明之外引用它,因爲它在那裏聲明。

我們無法辨別result變量的範圍,因爲您尚未顯示其聲明,但它至少「大於using聲明」。

更有意思的是result的值所指的對象在DbFactory處置後的可用性如何。這是特定於實現的,基本上......我期望如果訪問任何result屬性需要進一步的數據庫查詢(例如,獲取由外鍵引用的對象),那麼它將失敗,但是已獲取的任何東西都應該沒問題。

至於處置時間 - DbFactory將在using聲明的末尾處置。這與垃圾收集完全分開,大概Repository對象仍然會提及它 - 但是在工廠處理後它可能沒有用處。因此,如果您在using聲明後致電repo.Get(...),您可能會看到一個異常,具體取決於代碼實際在工廠中執行的操作,以及處置的工廠的行爲方式。再次,處置不是垃圾回收。它只是調用Dispose方法 - CLR不以任何特殊方式關心這一點。

+0

編輯該問題。我很困惑,repo變量在using語句或DbContext在使用語句之後處理並且回購將等待gc之後是否持有對DbContext的處置? – Sreejith

+1

Dispose與GarbageCollector無關,因爲Dispose方法不是析構函數,所以不會在Dispose方法時調用GC。 – Vir

+0

@jonskeet偉大的一點,我正在尋找處置的時機。 – Sreejith

3

DbFactory會被丟棄嗎?

是的。

在using語句中使用的repo變量的作用域是什麼?

repo範圍是,它是包含在塊的,所以對花括號(「{」,「}」),它的包在在這種情況下,它發生在與所述主體一致你的using聲明,是的。

+0

所以'repo'變量將不會舉行處置'DbFactory'正確的? – Sreejith

+0

@Rebornx它保存在同一個對象上,所以如果該對象被放置,並且存儲庫嘗試使用某個在處理對象上不受支持的操作,那麼它將不起作用。 – Servy

0

如果回購也是一次性的,你可能想出售它也爲exampe:

using(DbFactory db = new DbFactory()) 
using(Repository repo = new Repository<someobject>(db)) 
{ 
    result = repo.Get(somecondition); 
} 
+0

我知道。但是,將倉庫作爲一次性使用是否是一種好的模式? – Sreejith

0

此:

Repository repo; 
ResultObject result; 
using(DbFactory db = new DbFactory()) 
{ 
    repo = new Repository<someobject>(db); 
    result = repo.Get(somecondition); 
} 

是相同的,因爲這一個:

Repository repo; 
ResultObject result; 
{ 
    DbFactory db = new DbFactory() 
    repo = new Repository<someobject>(db); 
    result = repo.Get(somecondition); 
    db.Dispose(); 
} 

所以儘管db對象本身不會變幻(引用它將會保存在Repository實例中,它將處於Disposed/Closed狀態。尋找可能會破壞你的代碼的DbFactory的實現。

你沒有提供完整的代碼,它應該做的,但我認爲你應該往這個方向:

  1. 在Repository對象實現IDisposable和裏面配置DbFactory還有:

    public class Repository : IDisposable 
    { 
        private _dbFactory; 
    
        public Repository(DbFactory dbFactory) 
        { 
         _dbFactory = dbFactory; 
        } 
    
        public void Dispose() 
        { 
         _dbFactory.Dispose(); 
        } 
    } 
    
  2. 現在使用它像這樣:

    ResultObject result; 
    using (Repository repo = new Repository(new DbFactory()) 
    { 
        result = repo.Get(somecondition); 
    } 
    

或者用使用嵌套:

using (DbFactory db = new DbFactory()) 
{ 
    using(Repository repo = new Repository(db)) 
    { 
     result = repo.Get(somecondition); 
    } 
}