2013-09-25 33 views
0

我發現自己做這在我的課數據庫對象:通用處置和C#設置爲null

if (Db != null) 
{ 
    Db.Dispose(); 
    Db = null; 
} 

的幾個問題...

  1. 我是不是應該設計數據庫對象有一個更短的生命,所以 能夠把它放在using塊?
  2. 有沒有一種通用的方法來做到這一點,而不是每次我處理一些東西時寫3條線 ?

那些東西放在一邊,我感興趣的類似於這樣是否可行:

static void SafeDispose(ref IDisposable obj) 
{ 
    if (obj != null) 
    { 
     obj.Dispose(); 
     obj = null; 
    } 
} 
+1

就像你提到的,如果對象實現IDisposible,您可以使用使用。對於數據庫的東西,我會建議你使用using語句。 – Justin

+0

是什麼讓你避免使用使用塊? – Shawn

+1

此代碼是否在包含類的Dispose()方法中?如果是這樣,這個問題是問同樣的事情:[處置實現IDisposable的成員](http:// stackoverflow。COM /問題/ 3022650 /配置 - 的成員 - 即 - 實施 - IDisposable接口)。它有一個非常好的解決方案。另外,如果這是在'Dispose()'方法中,則不需要設置'Db = null;'它沒有任何好處。 –

回答

0
  1. 大抵如此。如果沒有看到更多的課程,就無法確定。但作爲一個經驗法則,我儘量避免使用可丟棄的字段或屬性(我假設它是如此,因爲如果它是局部變量,則可以使用using)。管理它們太難了,除非你的課程也是IDisposable,並且你用Dispose()方法清理它。
  2. 您可以將這些行重構爲他們自己的方法,例如, DisposeDb()
0
public static void MyDispose(ref DbContext db) 
    { 
     if (db != null) 
     { 
      db.Dispose(); 
      db = null; 
     } 
    } 

或類似的東西卡在某處類。

0
  1. 有沒有一種通用的方法來做到這一點,而不是每次處理某些東西時都寫3行?

爲了實現可重複使用的方式類似的東西,你可以創建一個靜態輔助方法:

public static class Disposable 
{ 
    public static void Dispose(ref IDisposable obj) 
    { 
     if (obj!= null) 
     { 
      obj.Dispose(); 
      obj = null; 
     } 
    } 
} 

您可以調用的方法是這樣的:

Disposable.Dispose(ref someDisposableObject); 

這不是因爲您無法將屬性傳遞給ref參數,因此要爲屬性工作。 ,使其成爲性能以及工作,你可以使用表達式:

public static class Disposable 
{ 
    public static void Dispose(Expression<Func<IDisposable>> expression) 
    { 
     var obj = expression.Compile().Invoke(); 
     if (obj == null) 
      return; 

     obj.Dispose(); 

     var memberExpression = expression.Body as MemberExpression; 
     if (memberExpression == null || !IsMemberWritable(memberExpression.Member)) 
      return; 

     var nullExpression = Expression.Constant(null, memberExpression.Type); 
     var assignExpression = Expression.Assign(memberExpression, nullExpression); 
     var lambdaExpression = Expression.Lambda<Action>(assignExpression); 

     var action = lambdaExpression.Compile(); 
     action.Invoke(); 
    } 

    private static bool IsMemberWritable(MemberInfo memberInfo) 
    { 
     var fieldInfo = memberInfo as FieldInfo; 
     if (fieldInfo != null) 
      return !fieldInfo.IsInitOnly && !fieldInfo.IsLiteral; 

     var propertyInfo = memberInfo as PropertyInfo; 
     if (propertyInfo != null) 
      return propertyInfo.CanWrite; 

     return true; 
    } 
} 

此方法適用於變量,字段和屬性。它處理任何可丟棄的對象,但只能將其設置爲null(如果它是可寫的)。

您可以用同樣的方式處理事情,這與方法Foo.CleanUp下面的例子說明:

public class Bar : IDisposable 
{ 
    // ... 
} 

public class Foo 
{ 
    private Bar _barField = new Bar(); 

    public Bar BarProperty { get; set; } = new Bar(); 

    public void CleanUp() 
    { 
     Disposable.Dispose(() => _barField); 
     Disposable.Dispose(() => BarProperty); 

     var barVariable = new Bar(); 
     Disposable.Dispose(() => barVariable); 
    } 
}