【问题标题】:Adding to List inside a Using block在 Using 块内添加到列表
【发布时间】:2013-11-26 17:05:42
【问题描述】:

我有一个类可以像这样实现 IDisposable

  public class SomeClass : IDisposable
{
    private IList<string> _someList = new List<string>();

    public IList<string> SomeList
    {
        get { return _someList; }
    }

    public void Dispose()
    {
        _someList = null;
    }
}

还有一个方法使用'using'块来创建这个类的两个实例并将它添加到这样的集合中

private static void Main(string[] args)
    {
        IList<SomeClass> classes = new List<SomeClass>();

        using (var sc = new SomeClass())
        {
            sc.SomeList.Add("a");
            classes.Add(sc);
        }

        using (var sc = new SomeClass())
        {
            sc.SomeList.Add("b");
            classes.Add(sc);
        }

        foreach (var a in classes)
        {
            Console.WriteLine(a.SomeList[0]);
        }

        Console.ReadLine();
    }

当我来到 foreach 遍历“类”中的元素时,我的两个对象的“SomeList”属性都为空。

我确实明白,由于每个 using 都执行 Dispose() 并且在 dispose 中,我将这两个列表设为空,因此它们将为空。

我的问题是如何在我的 dispose() 中停止将“SomeList”置空。

谢谢

--更新 1

更接近真实代码的东西

base.OnPreRender(e);

    Page page = HttpContext.Current.CurrentHandler as Page;
    HtmlHead head = (HtmlHead)page.Header;

    if (Settings.AreSet)
    {
        using (var noIndex = new HtmlMeta())
        {
            noIndex.Name = "somename";
            noIndex.Content = "somecontent";

            head.Controls.AddAt(0, noIndex);
        }
    }

    using (var machineName = new HtmlMeta())
    {
        machineName.Name = "somename2";
        machineName.Content = "somecontent2";

        head.Controls.AddAt(1, machineName);
    }

    UpdateHeader(head);

--更新#2 上述类的变体现在具有字符串属性,而不是列表。

public class SomeClass2 : IDisposable
{
    public string SomeString { get; set; }

    public void Dispose()
    {
        SomeString = string.Empty;
    }
}

对于下面的方法,它仍然做同样的事情。我的“类”包含“SomeClass2”列表,其中“SomeString”为空(我在 dispose() 中设置的内容)

IList<SomeClass2> classes = new List<SomeClass2>();

        using (var sc = new SomeClass2())
        {
            sc.SomeString = "a";
            classes.Add(sc);
        }

        using (var sc = new SomeClass2())
        {
            sc.SomeString = "a";
            classes.Add(sc);
        }

        foreach (var a in classes)
        {
            Console.WriteLine(a.SomeString);
        }


        Console.ReadLine();

【问题讨论】:

  • 我的问题是,您为什么要将Dispose 中的列表清空?这不是Dispose 的用途。

标签: c# collections dispose idisposable using


【解决方案1】:

您不想调用Dispose?只是不要使用using 声明。

或者把整个逻辑移到using里面:

private static void Main(string[] args)
{
    IList<SomeClass> classes = new List<SomeClass>();

    using (var sc = new SomeClass())
    {
        sc.SomeList.Add("a");
        classes.Add(sc);

        using (var sc = new SomeClass())
         {
            sc.SomeList.Add("b");
            classes.Add(sc);

            foreach (var a in classes)
            {
                Console.WriteLine(a.SomeList[0]);
            }
        }
    }
    Console.ReadLine();
}

顺便说一句:在这种情况下使用IDisposable 似乎毫无意义。 GC 无论如何都会收集未使用的 List&lt;T&gt; 对象。

【讨论】:

  • :) 我知道在这个例子中没有意义。但是这个例子是我们在生产中的代码块的简化。 1. 从 'using' 内部返回是不可能的 2. 在 'using' 块之后我们需要一个填充列表(并且 Dispose() 方法会做类似的事情,比如将列表归零)
  • @nesh_s 你能提供更接近真实代码的东西吗?你现在的代码没有意义。
  • @KendallFrey 我在上面的更新。另外,如果我可能会问为什么第一个样本没有意义?我正在尝试找到一种方法来处理类中的列表,同时在我的集合中保留它的副本。
  • 您不能处理列表,保留一份副本不会造成任何问题。
  • 只有当您不再需要它时,您才应该Dispose 对象。在您的所有示例中,您稍后确实需要该对象,因此您无法处置它。所以你要么扩大using范围,要么去掉它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多