与c#中的值类型和引用类型混淆

时间:2010-09-01 06:23:20

标签: c# parameters

我对参数有点困惑。当我们必须使用引用参数时何时应该使用c#中的方法/函数编程时使用值类型参数?

5 个答案:

答案 0 :(得分:16)

您需要非常明确参考类型与值类型之间的区别,以及“按值”参数与“按引用”参数之间的区别。

我有关于这两个主题的文章:

当使用作为引用类型的“by value”参数时,这两者相互作用:在这种情况下,按值复制的值是引用本身;您仍然可以修改引用引用的对象:

void SomeMethod(StringBuilder x)
{
    x.Append("Modified");
}
...

StringBuilder builder = new StringBuilder();
SomeMethod(builder);
Console.WriteLine(builder.ToString()); // Writes "Modified"

请注意,此相同,与传递引用语义相同...如果SomeMethod已更改为包含:

x = null;

然后不会使builder变量为null。但是,如果x参数更改为ref StringBuilder x(并相应更改了调用代码),则对x进行任何更改(例如将其设置为null)被调用者看到。

在设计自己的API时,我强烈建议您几乎不会使用refout参数。它们偶尔可以有用,但通常它们表明你试图从单个方法返回多个值,这通常更好地使用专门封装这些值的类型,或者可能是Tuple如果你使用的是.NET 4,那么这条规则有例外,当然,这是一个很好的起点。

答案 1 :(得分:0)

如果使用值类型参数,则无法在方法内更改其值(可以,但这不会反映用于调用方法的变量),而对于引用类型,您可以更改值。

答案 2 :(得分:0)

发送Value类型参数时,内部会将原始变量的副本发送到函数/方法。因此,如果您更改该函数内的值,则变量的原始值(我们在声明它的函数中)保持不变。

当您发送参考类型参数时,该函数将直接使用该变量的原始值。这是因为您只将该变量的内存引用发送给您的函数。

因此,根据变量的范围以及您希望如何在应用程序中使用该变量,您可以决定如何将其发送到您的函数。一个很好的例子可能是..如果你想在你的应用程序中计算更新一些全局计数器或状态变量,那么最好通过ref发送它,以便其他函数将在以后获得该变量的最新最新值

答案 3 :(得分:0)

有关此主题的最佳文章:

C# Heap(ing) Vs Stack(ing) in .NET: Part I

有四个部分。

答案 4 :(得分:0)

您可以尝试以下简单代码,我认为它可以帮助您更好地了解何时使用by-reference参数。

using System.Collections.Generic;
using System.Diagnostics.Contracts;

class Program
{
    static void Main(string[] args)
    {
        var list = new List<int>(new[] { 1, 2, 3, 4 });

        MakeItNull(list);
        Contract.Assert(list != null);

        MakeItRealNull(ref list);
        Contract.Assert(list == null);
    }


    static void MakeItNull(List<int> list)
    {
        list = null;
    }

    static void MakeItRealNull(ref List<int> list)
    {
        list = null;
    }
}