在C#中,它与Java中引用方法期间的对象创建相同吗

本文关键字:对象 创建 方法 它与 Java 引用 | 更新日期: 2023-09-27 18:26:03

我明天有一场编程比赛,我有一个快速问题:

在Java中,如果在方法的参数中传递一个对象,那么实际上得到的不是对象的副本,而是实际的对象。

它和C#一样吗?

public static void PunchyManager(string[] inputArray, ref int a, ref int b)
{
            string[] tempStrArray = inputArray;
}

如果我这样做,我会不会基本上制作一个指向inputArray的指针,而不是一个副本?

只是一个简短的问题,谢谢!

在C#中,它与Java中引用方法期间的对象创建相同吗

关于Java的基本问题是的。

更常见的情况是。引用类型(类)是通过引用传递的,这就像单个指针。对于可以真正修改调用程序外部引用的内容,即使在引用类型上也应该使用ref关键字。这类似于双指针(假设我们在C中引用指针进行指针类比)。

class RefRefExample
{
    static void Method(ref string s)
    {
        s = "changed"; 
    }
    static void Main()
    {
        string str = "original";
        Method(ref str);
        // str is now "changed"
    }
}

在上面的例子中,如果我们在不使用ref关键字的情况下传递str,我们将重新分配s的本地引用,而不是str的原始引用。通过通过引用传递我们的引用,我们也可以在函数之外修改原始引用。引用本身仍然按值复制(但复制的引用仍然指向相同的值),而不使用ref关键字。

http://msdn.microsoft.com/en-us/library/14akc2c7(v=vs.80).aspx


为了在场景中的实际使用,你正在描述的现代C#习惯用法通常使用列表,它们可能会比在竞争对手中编程更快地使用:

public static void PunchyManager(List<string> inputList, ref int a, ref int b)
{
    var tempList = new List<string>();
    foreach (var item in inputList)
       tempList.Add(item);     
}

处理原始输入列表会通过引用修改对象,因此会影响方法之外的原始值,而templList是一个副本-列表非常方便。此外,您可以使用.ToArray() 将它们转换回阵列

*edit哦,你想知道它在c#中是否与java相同,你的措辞有点偏离。

正确,如果你做

public static void main(String[] args)
{
    int myArray[] = new int[1];
    test(myArray);
    System.out.println(myArray[0]);
}
public void test(int[] array)
{
    array[0] = 1;
}

您将获得1 的输出

CLR中有两种对象:

  1. 引用类型(也称为"对象")
  2. 值类型(也称为"结构"或"structs",即使它们在技术上也是对象)

它们之间的区别在于"对象"位于堆上,而"结构"位于堆栈上。

Int32、Int64、Float、Double等类型都是值类型(structs)。您也可以定义自己的结构:

public struct MyStruct { ... }

因此,当您在它周围传递一个"结构"时,它是通过复制值来传递的。

示例:

int x = 5; //creates a value type on stack
int y = x; //makes a copy so now we have two objects on stack, not just one

"对象"是通过引用传递的。

object x = new Object(); //create an object, x holds a reference to this object
object y = x; // y now holds a reference to the same object x has a reference to.

当您传递引用类型时,通常不需要使用ref关键字。但是,如果要传递对值类型实例的引用,则可能需要使用此关键字。

是的,类实例在C#中作为引用传递。如果要传递值类型(如Int32)作为引用,则需要使用ref关键字。

问题是,如果您传递带有关键字ref的参数,那么方法内部变量的修改也会反映到调用者。这适用于偶数结构(exmple-int)。但对于struct或class,如果您传递带有out-ref/out的参数,则会将其假定为按值传递,这意味着方法内部的修改无法反映到structs的调用者。对于类,修改仍然会反映到调用者,而不会传递出ref。但是,StringBuilder sb=new StringBuilder()语句要求sb指向这个(新创建的新StringBuilder(())。因此,引用结将从调用者中指向的结移动到被调用者中的新StringBuilder()。必须永远记住这一点。

Pass by value with ref:
    static void Main(string[] args)
        {
            StringBuilder y = new StringBuilder();
            y.Append("hello");
            Foo(ref y);
Console.WriteLine(y);
       }
        private static void Foo(ref StringBuilder y)
        {
            StringBuilder sb = y;
            sb.Append("99");
        }
o/p : hello99
Pass by value without ref:
    static void Main(string[] args)
        {
            StringBuilder y = new StringBuilder();
            y.Append("hello");
            Foo(y);
Console.WriteLine(y);
       }
        private static void Foo(StringBuilder y)
        {
            StringBuilder sb = new StringBuilder
            sb.Append("99");
        }
o/p : hello

若要为数组分配不同的内容,您需要使用'ref'关键字来设置参数。

http://msdn.microsoft.com/en-us/library/szasx730(v=vs.71).aspx