C#7引用类型的引用返回 [英] C# 7 ref return for reference types

查看:26
本文介绍了C#7引用类型的引用返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在浏览一些代码,这些代码使用C#7的新功能并使用引用本地变量和返回功能。

对于value-types,其中ref局部变量获取引用(对实际存储空间)的引用,以及更新更新原始项的值,似乎非常简单。

稍加解释将有助于理解reference-types在引用局部变量时内存引用是如何工作的。我指向下面代码的最后一行:

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

推荐答案

C#的原始设计者将该特性命名为"ref"在我看来是一个坏主意。这会让人混淆引用类型和"ref"参数/返回。更好的理解"裁判"的方式是"别名"。也就是说,ref为现有变量提供了另一个名称。

在您的程序中,byRefarr[1]的另一个名称,无论arr[1]是值类型还是引用类型。如果arr[1]是字符串变量(请记住,数组元素是变量,您可以更改它们),则byref也是字符串变量,并且它是名称不同的相同的字符串变量。

请注意,arr也是一个变量;如果更改arr的值,则byRef不会出现。无论arr的值是多少,它都是同一数组的同一插槽的别名。

所以当你说

ref var byRef = ref GetSpecialItem_New(arr); //gets back arr[1]

然后

byRef.Name = "byRef"; 

完全相同
arr[1].Name = "byRef";

当你说

byRef = new CoolClass("newByRef", 50);

这与

完全相同
arr[1] = new CoolClass("newByRef", 50);

需要注意的是,如果您在分配byRef后更改了arr,您仍将拥有原始arr[1]的别名。

再说一遍:byRef只是arr[1]的另一种拼写方式,因此它始终使用byRef赋值时的arr值。值类型和引用类型没有不同。

相反,byVal不是arr[1]的别名。它是第二个变量,具有arr[1]内容的副本。当您分配给byVal时,您不是在分配给arr[1]。您正在赋值给byVal,它是一个不同的变量。

arr[1]内容是引用,且引用被复制到完全独立的存储位置。

这篇关于C#7引用类型的引用返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆