【问题标题】:C# method returns int-by value or referenceC# 方法返回 int-by 值或引用
【发布时间】:2020-03-13 11:29:42
【问题描述】:

我正在尝试确定方法返回的 int 将存储在哪里。我认为它是堆栈,但想澄清一下。场景如下:

public int returnInt()
{
   var returnVal=1:
   Return returnVal;
}

在这种情况下,我知道 returnVal 将存储在堆栈中,并在 returnInt 方法运行时弹出。实际上returnVal是一个值类型,所以不会通过引用传递。

我不清楚的部分如下:

public void callerMethod()
{
    var intVal=returnInt();
}

我认为这里发生的是返回实际值,并将其保存在堆栈上的新内存位置以供 callerMethod 使用。

谁能确认这是否正确?还请随时纠正我所说的任何其他不正确的地方...

【问题讨论】:

  • c# 中存储返回类型的位置几乎可以肯定是一个实现细节。
  • @RobertHarvey 你能扩展一下吗?
  • 值类型按值赋值(因此得名)。如果您有两个具有相同值类型的变量,并且您将一个变量分配给另一个变量,则与右侧变量关联的 将被复制到左侧变量。同样,如果您将函数(返回值类型)的返回值分配给变量,则会复制该值。当值类型的变量超出范围时,不需要清理。几乎所有其他内容都是实现细节;你不需要考虑的事情。
  • 您的问题是否与this 重复?您是在问整数是在堆栈上还是在堆上?或者你是在问where methods live(你似乎暗示你相信方法存在于堆栈上——它们也不存在于任何一个之上)。或者你是在问堆栈上为 returnVal 分配的内存位置是否被 intVal 重用?
  • @Flydog57 这就是答案——如果你写成答案我会接受

标签: c# memory stack heap-memory


【解决方案1】:

callerMethod() 中的值是一个新值,与returnInt() 中的值无关。

我希望下面的示例有所帮助。

static int myStaticInt = 333;
public static int returnInt()
{
    return myStaticInt;
}

public static void callerMethod()
{
    var i = returnInt();
    i += 100;
    Console.WriteLine(i);
}

public async static Task Main(string[] args)
{
    Console.WriteLine(myStaticInt);
    callerMethod();
    Console.WriteLine(myStaticInt);
}

输出

333
433
333

结果

myStaticInt 仍然是 333


这是来自Passing Value-Type Parameters (C# Programming Guide)的相关部分:

值类型变量直接包含其数据,而引用类型变量则包含对其数据的引用。通过值将值类型变量传递给方法意味着将变量的副本传递给方法。方法内部对参数的任何更改都不会影响存储在参数变量中的原始数据。

这里有一点关于来自 C# 规范的 Types 部分的赋值。

赋值给一个值类型的变量会创建一个被赋值的值的副本。这与分配给引用类型的变量不同,后者复制引用而不是引用标识的对象。


通过引用传递和返回值类型

请注意,可以通过引用传递和返回值类型。

请参阅Passing Value-Type Parameters (C# Programming Guide)Ref returns and ref locals通过引用传递值类型部分。

有了这些知识,现在让我们修改我们的示例并检查结果。

static int myStaticInt = 333;
public static ref int returnInt()
{
    //var returnVal = 1;
    return ref myStaticInt;
}

public static void callerMethod()
{
    ref var i = ref returnInt();
    i += 100;
    Console.WriteLine(i);
}

public async static Task Main(string[] args)
{
    Console.WriteLine(myStaticInt);
    callerMethod();
    Console.WriteLine(myStaticInt);
}

输出

333
433
433

结果

myStaticInt 现在是 433,而不是原来的 333

【讨论】:

    猜你喜欢
    • 2011-02-25
    • 2014-01-30
    • 1970-01-01
    • 2017-08-25
    • 2012-11-04
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多