【问题标题】:C# - Using nullable types as parametersC# - 使用可为空的类型作为参数
【发布时间】:2013-06-15 06:48:52
【问题描述】:

谁能告诉我接受一个函数的可空参数,然后在使用后将参数设置为空是否是个好主意?这是释放未使用资源的良好编程实践吗?例如:

public static bool SendEmail(MailAddressCollection? To, string Subject, string Body)
{
    // use the values stored in To, Subject, and Body to send the message.
    To = null;
}

【问题讨论】:

  • 1) string? 不是有效类型。 2) GC 会为您处理这些。
  • 不用担心,垃圾收集器会处理的。更多关于GC的信息msdn.microsoft.com/en-us/library/system.gc(v=vs.80).aspx
  • 我的意思不一定是字符串。我只是用我写的函数作为例子来说明我的意思。
  • 我宁愿使用可选参数msdn.microsoft.com/en-us/library/dd264739.aspxSendEmail(string subject="default subject", string body="default body)
  • 我刚刚注意到您的示例中的To 必须是Nullable<MailAddressCollection> 类型,其中MailAddressCollection 必须是struct。所以,To 是一个值类型。如果是这样,To 不受GC 约束,除非您将其装箱。接下来,将null 分配给To不是引用分配,而是默认值Nullable<MailAddressCollection> 的分配。因此,您不应该考虑GC,因为To 值存在于堆栈中,并在方法结束时立即被销毁(或者如果抖动决定更早)。

标签: c# .net performance garbage-collection


【解决方案1】:

,这不是一个好主意。你所做的没有实际影响。 您设置为 null 的唯一变量是该方法的本地变量。无论如何,该变量都会自动超出范围。

相反,如果您将该对象作为参数,则意味着在当前方法之外仍然存在对该对象的引用,并且您不会影响该引用。所以你在方法中做任何事情根本没有帮助GC。在这方面产生任何非本地效果的唯一方法是将所有参数作为ref 传递,从而能够将传递的变量设置为null。但是,这将是绝对可怕,因为每个看似无辜的方法调用都可能会破坏以后假定为非空的引用。

一般来说,在大多数应用程序中你应该做的就是不去想它。 GC 在检测未使用内存方面要好得多,因为它可以检查堆栈中的引用,并且可以访问 JIT 编译器发出的相关元数据,而您看不到这些元数据。

【讨论】:

    【解决方案2】:

    不,不是。你有一个 GC 来为你处理这个问题。您不是使用非托管语言,您不需要释放资源(当然,除非它们是 IDisposable)。

    【讨论】:

    • 我已更新我的代码以更准确地代表我的问题。
    【解决方案3】:

    不,这在 .NET 等托管环境中是一种不好的做法。 .NET 中的垃圾收集器可以自动收集没有引用的对象并从中释放内存。

    但也有极少数例外。您可以手动设置对 null 的引用并显式调用 GC:

    public static void ForceGC(ref object obj) {        
        obj = null;
        GC.Collect();
    }
    

    【讨论】:

    • 这种强制对象收集的方法是没用的。首先,如果您对一个对象的一个​​引用为空,它确实意味着不再有来自其他任何地方的引用(例如,立即调用者方法的调用者),因此不能保证该对象将被收集.其次,调用 GC.Collect 来收集一个对象是导致大量性能问题的直接途径,因为垃圾收集总是检查 所有 个对象,因此代价高昂。一般的建议是无论何时都要避免强制 GC。
    猜你喜欢
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 2016-09-28
    相关资源
    最近更新 更多