我可以一次性处理多个物体吗?

时间:2015-12-17 13:12:51

标签: c# .net dispose params ref

我有一个类实例,它实现了IDisposable接口,如下所示。

 finally
        {

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

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

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

        }

现在在实际代码中我有几个实例的实例需要在下面的finally块中处理

   static void DisposeInstance(params Instance[] instances)
    {
        for (int i = 0; i < instances.Length; i++)
        {

            if (instances[i] != null)
            {
                instances[i].Dispose();
                instances[i] = null;
            }
        }
    }

所以每当我想要Dispose时,我必须为每个对象编写上面的行。

我觉得我可以使用'params'关键字减少号码。 LOC(代码行)如下所示

 DisposeInstance(inst1, inst2, inst3);

并在单个镜头中传递实例,如

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >


    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/txtNumber"
        android:layout_weight="1"
        android:layout_gravity="center_horizontal"
        android:text="@string/txtNumber" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/txtName"
        android:id="@+id/txtName"
        android:layout_gravity="top|bottom"
        android:layout_weight="1" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/txtScore"
        android:id="@+id/txtScore"
        android:layout_weight="1" />


</LinearLayout>

但是上面的函数只会处理Instance的本地副本,并且不会完全处理实际的对象(实例)。

所以我的问题是,如果有任何方法可以实现我的目标,即一次性处理对象并减少LOC。

我也可以使用'ref'关键字和'params'(我知道这会产生编译错误),但是不知怎的混合这两个以获得结果?

提前致谢!

5 个答案:

答案 0 :(得分:3)

您不需要将对象设置为null,使用C#6可以使用Null-Propagation语法:

inst1?.Dispose();
inst2?.Dispose();
inst3?.Dispose();

这大大降低了噪音。

答案 1 :(得分:0)

您可以将列表发送到您的方法

   static void DisposeInstancies(List<Instance> instances)
    {
        for (int i = 0; i < instances.Length; i++)
        {

            if (instances[i] != null)
            {
                instances[i].Dispose();
                instances[i] = null;
            }
        }
    }

所以:

DisposeInstancies(new List<Instance> {inst1, inst2, inst3});

答案 2 :(得分:0)

您可以尝试使用using statement自动处理对象。像这样:

using (MyClass inst1 = new MyClass())
using (MyClass1 inst2 = new MyClass1())
using (MyClass2 inst3 = new MyClass2())
{
    // code 
}  
  

using语句允许程序员指定对象的时间   使用资源应该释放它们。提供给使用的对象   语句必须实现IDisposable接口。这个界面   提供Dispose方法,该方法应该释放对象   资源。

答案 3 :(得分:0)

  

但是上面的函数只会处理Instance的本地副本,并且不会完全处理实际的对象(实例)。

它处理对象(或至少调用方法Dispose()),但它不在调用者范围内将引用设置为null。实际上,只有复制的引用值DisposeInstance范围内设置为null。

你真的需要将它设置为null吗?如果您的目标是避免因多次调用Dispose()而导致的错误,那么您应该使用布尔来控制状态:

private bool hasBeenDisposed ; 

public void Dispose() 
{
    if (!hasBeenDisposed)
    {
        DisposeInstance(inst1, inst2, inst3);
        hasBeenDisposed = true ; 
    }
}

此外,您应将DisposeInstance args更改为IDisposable []以获得可重用性和可读性。

static void DisposeInstance(params IDisposable [] instances)
{
    for (int i = 0; i < instances.Length; i++)
    {

        if (instances[i] != null)
        {
            instances[i].Dispose();
            instances[i] = null;
        }
    }
}

答案 4 :(得分:0)

关于处置的一点点。

处理对象时,清除大型内容对象的对象。您只需孤立您正在处理的对象的内容,以便GC可以自由选择它们。

如果你想要在IDIposposable实现的对象中没有任何大对象或数组,那么你真的不需要处理它。如果你需要内存中的空间,那么只需将其置空以强制它超出范围并进入GC。

(这里有一个角落的情况,GC停止你的程序收集,所以如果你有很多小物件,那么当你有“时间”时处理它们是一个很好的方法去处理它们后记得抑制GC)

如开发人员所做的那样,处置是一种判断。在大多数情况下,您并不真正需要它,在多种情况下,处理包含较大数组/集合的对象很不错。

因此,对于您的问题,我建议您在完成课程后处理,而不是等到“范围”结束时,或者将它们放在列表中并稍后处理。

Queue<IDisposable> toDispose = new Queue<IDisposable>();
private void DisposeObjects(){
    while(toDispose.Any()){
        toDispose.Dequeue()?.Dispose();
    }
}

MSDN: Dispose Pattern

相关问题