if (!someList.Contains(new listItem(arg1, args2)))
{
// Do some stuff
}
对于上面的代码段,someList
是一个结构体列表,listItem
是结构体。
在这种情况下使用 new 运算符会导致内存泄漏吗?或者这是一般不良做法的一个例子?我在 SO 和 Google 上进行了搜索,但找不到专门解决此问题的问题。
if (!someList.Contains(new listItem(arg1, args2)))
{
// Do some stuff
}
对于上面的代码段,someList
是一个结构体列表,listItem
是结构体。
在这种情况下使用 new 运算符会导致内存泄漏吗?或者这是一般不良做法的一个例子?我在 SO 和 Google 上进行了搜索,但找不到专门解决此问题的问题。
您必须非常努力地在 C# 中创建内存泄漏。这是可能的,但它意外发生的情况并不多(除了与没有如此简单的内存管理的其他语言进行互操作时)。不过,我不会在这里讨论边缘情况。
以下是该对象的内存外观:
Contains
返回它的调用堆栈上的参数将被“释放”,所以我们现在回到只有一个变量。即使new
使用了关键字,也不会在堆上创建结构。它仍然在堆栈上创建。在 C#new
中显式调用任何构造函数时使用(禁止反射)并且不指示堆上的分配(它在 C++ 中的方式)。
还值得一提的是,即使这是一个类而不是结构,也不会导致任何内存泄漏。该对象最终会在堆上,但垃圾收集器会在不再需要它之后的某个时候清理它。您在这里没有做任何会导致在不需要对象时保留对对象的引用的事情(而且我知道这Contains
不会做任何会阻止它被收集的恶作剧;如果它是一些未知的功能,它就是可能但不太可能他们会做一些有意义的事情)。
这与结构有关并不少见。例如,在使用DateTime
s 时,说起来更易读:
if (fooDate == new DateTime(2000, 1, 30, 11, 30, 0))
比
if (fooDate.Year = 2000 && fooDate.Month = 1 && fooDate.Day = 30 && ...)
这不是内存泄漏,我也没有必要称之为坏风格(它在 MSDN示例用法中使用)
但可能不是我会这样做 - 我会做类似的事情:
if (!someList.Any(o => o.Arg1 == arg1 && o.Arg2 == arg2))
{
// Do some stuff
}
这是可读性的问题。我发现像你展示的那样完成后更难阅读我更喜欢单独声明列表
性能或内存泄漏没有差异
此外,当您单独声明一个列表时,您可以给您的列表一个有意义的名称
例如 var listOfDays = 新列表.....