我正在创建一个函数,我需要传递一个对象,以便它可以被函数修改。有什么区别:
public void myFunction(ref MyClass someClass)
and
public void myFunction(out MyClass someClass)
我应该用哪个,为什么?
我正在创建一个函数,我需要传递一个对象,以便它可以被函数修改。有什么区别:
public void myFunction(ref MyClass someClass)
and
public void myFunction(out MyClass someClass)
我应该用哪个,为什么?
当前回答
Ref表示Ref参数中的值已经设置,方法可以读取和修改它。 使用ref关键字等同于说调用方负责初始化形参的值。
Out告诉编译器,对象的初始化是由 函数需要赋值给out形参。 没有分配是不允许的。
https://www.codemaggot.com/ref-and-out-keywords/
其他回答
Ref和out的行为类似,只是有一些不同。
引用变量必须在使用前初始化。Out变量无需赋值即可使用 Out形参必须被使用它的函数视为未赋值。因此,我们可以在调用代码中使用初始化的out形参,但该值将在函数执行时丢失。
扩展狗和猫的例子。带有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告诉编译器对象将在函数内部初始化。
所以当ref是双向的,out是唯一的。
From the standpoint of a method which receives a parameter, the difference between ref and out is that C# requires that methods must write to every out parameter before returning, and must not do anything with such a parameter, other than passing it as an out parameter or writing to it, until it has been either passed as an out parameter to another method or written directly. Note that some other languages do not impose such requirements; a virtual or interface method which is declared in C# with an out parameter may be overridden in another language which does not impose any special restrictions on such parameters.
从调用者的角度来看,c#在很多情况下假设调用带有out形参的方法时,会导致传入的变量在未被读取之前就被写入。当调用用其他语言编写的方法时,这个假设可能不正确。例如:
struct MyStruct
{
...
myStruct(IDictionary<int, MyStruct> d)
{
d.TryGetValue(23, out this);
}
}
如果myDictionary标识了一个用c#以外的语言编写的dictionary <TKey,TValue>实现,即使MyStruct s = new MyStruct(myDictionary);看起来像一个任务,它可能会留下未修改的s。
注意用VB编写的构造函数。NET与c#中的方法不同,它不假设被调用的方法是否会修改任何out参数,并且无条件地清除所有字段。上面提到的奇怪行为不会发生在完全用VB或完全用c#编写的代码中,但是当用c#编写的代码调用用VB.NET编写的方法时就会发生。
注意,在函数内部传递的引用参数是直接处理的。
例如,
public class MyClass
{
public string Name { get; set; }
}
public void Foo()
{
MyClass myObject = new MyClass();
myObject.Name = "Dog";
Bar(myObject);
Console.WriteLine(myObject.Name); // Writes "Dog".
}
public void Bar(MyClass someObject)
{
MyClass myTempObject = new MyClass();
myTempObject.Name = "Cat";
someObject = myTempObject;
}
这会写狗,而不是猫。因此,您应该直接在someObject上工作。