简体   繁体   English

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

[英]In C#, is it the same as in Java refering to object creation during methods?

I have a programming competition tomorrow and I have a quick question: 我明天有一个编程竞赛,我有一个简单的问题:

In Java, if you would pass an object in a parameter for a method, you actually got not a copy of the object, but the actual object. 在Java中,如果要在方法的参数中传递对象,则实际上并不是对象的副本,而是实际对象的副本。

Is it the same as C#? 它和C#一样吗?

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

If I do that will I basically make a pointer to inputArray, instead of having a copy? 如果我这样做,我基本上会做一个指向inputArray的指针,而不是一个副本?

Just a quick question, thanks! 只是一个简单的问题,谢谢!

In regard to your basic question in relation to Java Yes. 关于Java的基本问题是。

More generally Yes and no . 更普遍的 Reference types (classes) are passed by reference which is like a single pointer . 引用类型(类)通过引用传递,类似于单个指针 For something that can truly modify references outside the caller you should use the ref keyword even on reference types. 对于可以真正修改调用者之外的引用的东西,你应该使用ref关键字甚至引用类型。 This is similiar to a double pointer (assuming we are referring to pointers as they work in C for our pointer analogies). 这类似于双指针 (假设我们指的是指针,因为它们在C中用于我们的指针类比)。

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

In the above example if we passed str without using the ref keyword we would reassign the local reference of s instead of the original reference of str. 在上面的例子中,如果我们在不使用ref关键字的情况下传递str,我们将重新分配s的本地引用而不是str的原始引用。 By passing our reference by reference we can modify the original reference outside of the function as well. 通过引用传递我们的引用我们也可以修改函数外部的原始引用。 References themselves are still copied by value (but the copied reference still points to the same value) without the ref keyword. 如果没有ref关键字,引用本身仍会按值复制(但复制的引用仍指向相同的值)。

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


For practical usage in the scenario you are describing the modern C# idiom usually uses lists and they will likely be much faster to use as far as programming in your competition: 对于在场景中的实际用法,您描述的是现代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);     
}

Working on the original input list would modify objects through the reference so you would be affecting the original values outside of the method whereas the templList is a copy - Lists are very convenient . 处理原始输入列表将通过引用修改对象,因此您将影响方法之外的原始值,而templList是副本 - 列表非常方便 Furthermore you can convert them back to Arrays using .ToArray() 此外,您可以使用.ToArray()将它们转换回数组

*edit Oh, you wish to know if it is the same in c# as java, your wording was a bit off. *编辑哦,你想知道c#和java是否一样,你的措辞有点偏。

Correct, if you do 正确的,如果你这样做

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;
}

You will get an output of 1 您将获得1的输出

In CLR there are two kinds of objects: 在CLR中有两种对象:

  1. Reference types (also known as just "objects") 引用类型(也称为“对象”)
  2. Value types (also known as "structures" or "structs", even they are technically objects too). 值类型(也称为“结构”或“结构”,即使它们在技术上也是对象)。

The difference between them is that "objects" are located on heap, when "structs" are located on stack. 它们之间的区别在于,当“结构”位于堆栈上时,“对象”位于堆上。

Types like Int32, Int64, Float, Double, etc are value types (structs). Int32,Int64,Float,Double等类型是值类型(结构)。 You can also define your own structure: 您还可以定义自己的结构:

public struct MyStruct { ... }

Therefore, when you pass a "struct" around it is passed by copying the value. 因此,当您传递“struct”时,它会通过复制值传递。

Example: 例:

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

"Objects" are passed by reference. “对象”通过引用传递。

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.

When you pass reference types around you generally don't need to use a ref keyword. 当您传递引用类型时,通常不需要使用ref关键字。 However, if you want to pass a reference to a value type instance you may want to use this keyword. 但是,如果要将引用传递给值类型实例,则可能需要使用此关键字。

Yes, class instances are passed as references in C#. 是的,类实例作为C#中的引用传递。 If you want to pass value type (like Int32) as reference you need to use ref keyword. 如果要将值类型(如Int32)作为引用传递,则需要使用ref关键字。

Thing is, If you pass the parameter with keyword ref, modification of the variable inside the method will be reflected to caller as well. 事情是,如果您使用关键字ref传递参数,方法内部变量的修改也将反映给调用者。 This is applicable to even struct(exmple int). 这适用于even struct(exmple int)。 But for struct or class, if you pass the parameter with out ref/out, this will be assumed as pass by value, which means, modification inside the method cannot be reflected to caller for structs. 但是对于struct或class,如果你传递带有ref / out的参数,这将被假定为pass by value,这意味着,方法内部的修改不能反映给结构的调用者。 For classes, modification will be reflected to caller still without passing with out ref. 对于类,修改将反映给调用者仍然没有传递给ref。 BUT, StringBuilder sb = new StringBuilder() statement ask the sb to point to this one (an newly created new StringBuilder()). 但是,StringBuilder sb = new StringBuilder()语句要求sb指向这一个(新创建的新StringBuilder())。 So reference knot will be moved from one which was pointed in the caller to new StringBuilder() in the callee. 因此引用结将从调用者中指向的引用移动到被调用者中的新StringBuilder()。 This has to be remembered always. 必须始终记住这一点。

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

To assign something different to your array you'd want to have the parameter use the 'ref' keyword. 要为您的数组指定不同的内容,您需要使用'ref'关键字。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM