Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用;清晰的;方法与新对象_C#_.net - Fatal编程技术网

C# 使用;清晰的;方法与新对象

C# 使用;清晰的;方法与新对象,c#,.net,C#,.net,在.NET framework中,许多System.Collection类上都有Clear方法。与使用新对象替换引用相比,使用它是否有明显的优势 谢谢。如果您对同一对象有其他引用,并且希望所有引用都指向同一对象,则需要使用Clear 例如,您可能有一个工作队列,用于存储要执行的任务。在一个或多个线程中,您将工作项从该队列中取出(当然,您使用锁定来确保一次最多使用一个线程访问该队列)。如果在某个时刻您想清空队列,那么您可以使用Clear,所有线程仍将指向同一个对象 当您使用Clear时,所有项目都

在.NET framework中,许多System.Collection类上都有
Clear
方法。与使用新对象替换引用相比,使用它是否有明显的优势


谢谢。

如果您对同一对象有其他引用,并且希望所有引用都指向同一对象,则需要使用
Clear

例如,您可能有一个工作队列,用于存储要执行的任务。在一个或多个线程中,您将工作项从该队列中取出(当然,您使用锁定来确保一次最多使用一个线程访问该队列)。如果在某个时刻您想清空队列,那么您可以使用
Clear
,所有线程仍将指向同一个对象

当您使用
Clear
时,所有项目都将被删除,
Count
将为0,但
容量将保持不变。通常,
容量保持不变是一件好事(为了提高效率),但在极端情况下,您可能有大量的项目,希望最终释放内存


上面的MSDN链接还提到Clear是一个O(n)操作。然而,简单地替换引用将是一个O(1)操作,然后最终它将被垃圾收集,但可能不会立即进行。但是替换引用还意味着需要重新分配构成容量的内存。

替换引用不会立即释放收集,它需要等待垃圾收集器处理对象


如果要重新使用同一对象集合,请使用.Clear()。如果不使用,则这两个对象将在内存中保留一段时间。

Brian是正确的,但更具体地说,
Clear
方法将从集合的当前实例中删除所有项。实例化一个新集合并将其引用分配给您的变量将为您提供一个全新的实例,并且可能会导致一些意外后果,具体取决于其他人是否持有对旧实例的引用。如果另一个线程具有对该集合的引用,则即使您创建了新实例,它们仍将保留对旧集合的引用。

这可能取决于集合对象的大小。我认为当你说new时,它会创建对象的原始大小,clear只会清除内容,但大小仍然相同。

如果你在处理大数据和频繁操作IEnumerable项,new object会导致内存问题。看看我的例子:

class Lol
{
    int i;
    string s;
    public Lol(int ti, string ts)
    {
        i = ti;
        s = ts;
    }
}

class Program
{
    static List<Lol> lol = new List<Lol>();

    static void Main(string[] args)
    {
        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Stopwatch sw = new Stopwatch();
        sw.Start();
        ListCleaner();
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Console.WriteLine("lol");

        ListCleaner();

        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Console.WriteLine("lol");

        ListCleaner();

        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Console.WriteLine("lol");

        ListCleaner();

        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Console.WriteLine("lol");

        ListCleaner();

        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Console.WriteLine("lol");

        ListCleaner();

        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Console.WriteLine("lol");

        ListCleaner();

        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Console.WriteLine("lol");

        ListCleaner();

        for (int i = 0; i < 10000000; ++i)
            lol.Add(new Lol(i, i.ToString()));

        Console.WriteLine("lol");

        ListCleaner();
    }

    static void ListCleaner()
    {
        //lol = new List<Lol>();
        lol.Clear();
    }
}
类Lol
{
int i;
字符串s;
公共Lol(整数ti,字符串ts)
{
i=ti;
s=ts;
}
}
班级计划
{
静态列表lol=新列表();
静态void Main(字符串[]参数)
{
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
秒表sw=新秒表();
sw.Start();
ListCleaner();
sw.Stop();
控制台写入线(软件延迟毫秒);
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
控制台写入线(“lol”);
ListCleaner();
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
控制台写入线(“lol”);
ListCleaner();
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
控制台写入线(“lol”);
ListCleaner();
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
控制台写入线(“lol”);
ListCleaner();
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
控制台写入线(“lol”);
ListCleaner();
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
控制台写入线(“lol”);
ListCleaner();
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
控制台写入线(“lol”);
ListCleaner();
对于(int i=0;i<10000000;++i)
lol.Add(新的lol(i,i.ToString());
控制台写入线(“lol”);
ListCleaner();
}
静态void ListCleaner()
{
//lol=新列表();
lol.Clear();
}
}
如果使用此选项,则在运行时不会遇到任何问题。但若您注释掉ListCleaner中的Clear行,并取消注释新的对象行,则会出现内存问题

顺便说一句,“Console.WriteLine(sw.elapsedmillyses);”(您可以使用ElapsedTicks,因为它的值与其他值有很大的不同。)行告诉您,清除需要更多的时间,但可以避免内存问题


我注意到所有这些都是在调试代码时发生的(即使是在发布模式下)。运行.exe文件没有问题。

虽然这是事实,但这并不是大多数人关心的区别。@IgnacioVazquez Abrams。我当然会关心收集是否很大。但是清除的对象也不会立即被垃圾收集。这得到了大部分,我想补充的唯一一件事是,在处理已被监视的可观察收集时,您希望使用清除。的可能重复