我正在创建一个函数,我需要传递一个对象,以便它可以被函数修改。有什么区别:

public void myFunction(ref MyClass someClass)

and

public void myFunction(out MyClass someClass)

我应该用哪个,为什么?


当前回答

我可能不太擅长这一点,但肯定字符串(即使他们在技术上是引用类型和生活在堆上)是通过值传递,而不是引用?

        string a = "Hello";

        string b = "goodbye";

        b = a; //attempt to make b point to a, won't work.

        a = "testing";

        Console.WriteLine(b); //this will produce "hello", NOT "testing"!!!!

这就是为什么你需要引用,如果你想要改变存在于函数的作用域之外,否则你不传递引用。

据我所知,你只需要引用结构/值类型和字符串本身,因为字符串是一个引用类型,假装它是,但不是一个值类型。

我可能完全错了,我是新来的。

其他回答

我可能不太擅长这一点,但肯定字符串(即使他们在技术上是引用类型和生活在堆上)是通过值传递,而不是引用?

        string a = "Hello";

        string b = "goodbye";

        b = a; //attempt to make b point to a, won't work.

        a = "testing";

        Console.WriteLine(b); //this will produce "hello", NOT "testing"!!!!

这就是为什么你需要引用,如果你想要改变存在于函数的作用域之外,否则你不传递引用。

据我所知,你只需要引用结构/值类型和字符串本身,因为字符串是一个引用类型,假装它是,但不是一个值类型。

我可能完全错了,我是新来的。

迟了回答,但想到了发帖。可能比其他答案更清楚一点。

ref的关键字:

ref is a keyword which is used to pass any value by reference(refer to call by value and call by reference in programming for further knowledge). In short, you declare and initialize a value for example let us say int age = 5; so this age is saved in the memory by holding a place of 4 bytes. Now if you are passing this age variable to another method with ref (which means passing them by reference and not by value) then the compiler will just pass the reference of that variable or in clear terms, the memory address of the place where the variable is stored and the called method receives this address and directly accesses the data in that address. So obviously any change to that data will happen also to the variable present in the calling method.

示例:我提供了我的stackoverflow帐户的密码并告诉他 他可以做任何他想做的事,他可以提问或回答。的 问题是,他做的任何改变都会直接影响到我的账户。

关键字:

Out和in类似于它们都传递变量的引用。现在我们知道,两者都需要传递变量的引用,很明显,内存中必须有一个地方保存变量的字节。但在out的情况下没有初始化。因为要求是,被调用的方法必须初始化值并返回它。

示例:我将stackoverflow站点地址发送给我的朋友并询问 让他帮我开个账户,把证件还给我。

关键字:

现在,in关键字的工作原理与ref关键字完全相同,只有一个条件,即作为引用传递的值不能被修改。

示例:我提供了我的stackoverflow帐户的密码,但告诉了他 不做任何事情,除了阅读或浏览网站。不要问 问题,没有答案,没有投票,什么都没有。

MSDN引用:

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier

希望以上说明清楚了。

扩展狗和猫的例子。带有ref的第二个方法更改调用者引用的对象。所以叫“猫”!!

    public static void Foo()
    {
        MyClass myObject = new MyClass();
        myObject.Name = "Dog";
        Bar(myObject);
        Console.WriteLine(myObject.Name); // Writes "Dog". 
        Bar(ref myObject);
        Console.WriteLine(myObject.Name); // Writes "Cat". 
    }

    public static void Bar(MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

    public static void Bar(ref MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

对于那些以身作则的人(比如我),以下是安东尼·科索夫所说的。

我创建了一些ref、out和其他例子来说明这一点。我并没有介绍最佳实践,只是举例来理解它们之间的差异。

https://gist.github.com/2upmedia/6d98a57b68d849ee7091

有两个主要的区别,我想举例说明:

Ref和out通过reference传递,hense;

 class Program
    {
        public static void Main(string[] args)
        {
            var original = new ObjectWithMememberList(3);
            Console.WriteLine(original.MyList.Capacity); // 3
            ChangeList(original.MyList);
            Console.WriteLine(original.MyList.Capacity); // 3
        }

        static void ChangeList(List<int> vr)
        {
            vr = new List<int>(2);
        }
}

but:

 class Program
    {
        public static void Main(string[] args)
        {
            var original = new ObjectWithMememberList(3);
            Console.WriteLine(original.MyList.Capacity); // 3
            ChangeList(ref original.MyList);
            Console.WriteLine(original.MyList.Capacity); // 2
        }

        static void ChangeList(ref List<int> vr)
        {
            vr = new List<int>(2);
        }
}

out也是一样。 2. Ref参数必须是一个可赋值变量。 hense:

ChangeList(ref new List<int>()); // Compile Error [might not be initialized before accessing]

but:

List<int> xs;
ChangeList(out xs); // Compiles