我正在查看使用C# 7的新特性,并使用ref locals & returns功能的一些代码。
对于值类型(value-types
),这似乎非常简单,其中ref local变量获取引用(到实际存储),并更新该值将更新原始项的值。
关于引用类型(reference-types
)的ref locals如何工作,需要一点解释。我指向下面代码的最后一行:
// A simple class
public class CoolClass
{
public string Name { get; set; }
public int Id { get; set; }
public CoolClass(string name, int id) => (Name, Id) = (name, id);
}
//Dummy method that returns first element with Id > 100
public CoolClass GetSpecialItem_Old(CoolClass[] arr)
{
for (int i = 0; i < arr.Length; i++)
if (arr[i].Id > 100)
{
return arr[i];
}
throw new Exception("Not found");
}
//Same as the other one, but returns by ref C# 7
public ref CoolClass GetSpecialItem_New(CoolClass[] arr)
{
for (int i = 0; i < arr.Length; i++)
if (arr[i].Id > 100)
{
return ref arr[i];
}
throw new Exception("Not found");
}
public void TestMethod()
{
var arr = new CoolClass[]
{
new CoolClass("A", 10),
new CoolClass("B", 101),
new CoolClass("C", 11)
};
var byVal = GetSpecialItem_Old(arr); //gets back arr[1]
byVal.Name = "byVal"; //arr[1] = { "byVal", 101 }
byVal = new CoolClass("newByVal", 25); //arr[1] = { "byVal", 101 }
ref var byRef = ref GetSpecialItem_New(arr); //gets back arr[1]
byRef.Name = "byRef"; //arr[1] = { "byRef", 101 }
//Here it has a different behaviour
byRef = new CoolClass("newByRef", 50); //arr[1] = { "newByRef", 50 }
}
ref var byRef
基本上是对arr[1]
的同一引用,因此如果你byRef = new ...
,在底层实际上是arr[1] = new ...
。 - Caramiriel