在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的指针,而不是一个副本?
只是一个简短的问题,谢谢!
关于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中有两种对象:
- 引用类型(也称为"对象")
- 值类型(也称为"结构"或"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