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

public void myFunction(ref MyClass someClass)

and

public void myFunction(out MyClass someClass)

我应该用哪个,为什么?


当前回答

 public static void Main(string[] args)
    {
        //int a=10;
        //change(ref a);
        //Console.WriteLine(a);
        // Console.Read();

        int b;
        change2(out b);
        Console.WriteLine(b);
        Console.Read();
    }
    // static void change(ref int a)
    //{
    //    a = 20;
    //}

     static void change2(out int b)
     {
         b = 20;
     }

你可以检查这段代码,它会向你描述它的完全不同 当你使用“ref”时,这意味着你已经初始化了int/string

但 当你使用out的时候 无论你是否初始化int/string,它都适用于这两种情况 但是u必须在函数中初始化int/string

其他回答

它们几乎是一样的——唯一的区别是,作为out形参传递的变量不需要初始化,使用ref形参的方法必须将其设置为某个值。

int x;    Foo(out x); // OK 
int y;    Foo(ref y); // Error

Ref形参用于可能被修改的数据,out形参用于已经使用返回值的函数(例如int.TryParse)的额外输出数据。

ref修饰符的意思是:

该值已经设置,并且 该方法可以读取和修改它。

out修饰符的意思是:

Value未被设置,并且在设置之前不能被方法读取。 方法必须在返回之前设置它。

除了允许你将别人的变量重新分配给类的不同实例,返回多个值等,使用ref或out可以让别人知道你需要从他们那里得到什么,以及你打算用他们提供的变量做什么

You don't need ref or out if all you're going to do is modify things inside the MyClass instance that is passed in the argument someClass. The calling method will see changes like someClass.Message = "Hello World" whether you use ref, out or nothing Writing someClass = new MyClass() inside myFunction(someClass) swaps out the object seen by the someClass in the scope of the myFunction method only. The calling method still knows about the original MyClass instance it created and passed to your method You need ref or out if you plan on swapping the someClass out for a whole new object and want the calling method to see your change Writing someClass = new MyClass() inside myFunction(out someClass) changes the object seen by the method that called myFunction

还有其他程序员

他们想知道你将如何处理他们的数据。假设您正在编写一个将被数百万开发人员使用的库。你想让他们知道当他们调用你的方法时你要对他们的变量做什么

Using ref makes a statement of "Pass a variable assigned to some value when you call my method. Be aware that I might change it out for something else entirely during the course of my method. Do not expect your variable to be pointing to the old object when I'm done" Using out makes a statement of "Pass a placeholder variable to my method. It doesn't matter whether it has a value or not; the compiler will force me to assign it to a new value. I absolutely guarantee that the object pointed to by your variable before you called my method, will be different by the time I'm done

顺便说一下,在c# 7.2中也有一个in修饰符

And that prevents the method from swapping out the passed in instance for a different instance. Think of it like saying to those millions of developers "pass me your original variable reference, and I promise not to swap your carefully crafted data out for something else". in has some peculiarities, and in some cases such as where an implicit conversion might be required to make your short compatible with an in int the compiler will temporarily make an int, widen your short to it, pass it by reference and finish up. It can do this because you've declared you're not going to mess with it.


微软对数值类型的.TryParse方法做到了这一点:

int i = 98234957;
bool success = int.TryParse("123", out i);

通过将参数标记为out他们在这里积极地声明"我们肯定会将你苦心制作的98234957值更改为其他值"

当然,对于像解析值类型这样的事情,它们有点不得不这样做,因为如果parse方法不允许将值类型替换为其他类型,那么它就不能很好地工作。但是想象一下在你创建的库中有一些虚构的方法:

public void PoorlyNamedMethod(out SomeClass x)

你可以看到它是一个out,因此你可以知道,如果你花了几个小时处理数字,创建一个完美的SomeClass:

SomeClass x = SpendHoursMakingMeAPerfectSomeClass();
//now give it to the library
PoorlyNamedMethod(out x);

那真是浪费时间,花那么多时间来做一节完美的课。它肯定会被丢弃,并被PoorlyNamedMethod取代

裁判上场又出局。

您应该优先使用out,只要它能满足您的需求。

Ref告诉编译器对象在进入函数之前已经初始化,而out告诉编译器对象将在函数内部初始化。

所以当ref是双向的,out是唯一的。