C# ref 是像 C/C++ 中的指针还是 C++ 中的引用?

2024-03-12

我正在与ref并且不太明白“它像 C/C++ 中的指针还是 C++ 中的引用?”

为什么我会问你这么弱的问题? 因为,当我阅读 C#/.NET 书籍、msdn 或与 C# 开发人员交谈时,我对以下原因感到困惑:

  • C# 开发者建议不要使用ref在函数的参数中,e.g. ...(ref Type someObject)对他们来说味道不好,他们建议...(Type someObject),我实在是不太明白这个建议。我听到的原因是:更好地使用对象的副本,然后将其用作返回值,而不是通过引用破坏内存等......我经常听到有关数据库连接对象的此类解释。根据我的普通 C/C++ 经验,我真的不明白为什么在 C# 中使用引用是一件坏事?我控制对象的生命周期及其内存分配/重新分配等...我在书籍和论坛中阅读的只是建议it's bad, because you can corrupt your connection and cause a memory leak by a reference lose,所以我控制了对象的生命,我可以手动控制我真正想要的,那么为什么它不好呢?
  • 现在读不同的书,和不同的人交谈,我不太明白是什么ref一个指针(*) 或类似 C++ 中的引用&?我记得 C/C++ 中的指针总是分配一个大小为void*类型 - 4 字节(有效大小取决于体系结构),其中承载结构或变量的地址。在 C++ 中通过传递引用&堆/堆栈中没有新的分配,并且您使用内存空间中已定义的对象,并且没有像普通 C 中那样在外部为指针分配内存。那么什么是ref在 C# 中? .NET VM 是否像普通 C/C++ 中的指针一样处理它?GC为指针分配临时空间还是像 C++ 中的引用一样工作?做ref仅适用于托管类型或值类型,例如bool, int最好换一个unsafe代码并以非托管风格传递指针?

在 C# 中,当您看到引用引用类型(即用class代替struct),那么你基本上总是通过指针处理对象。在 C++ 中,默认情况下所有内容都是值类型,而在 C# 中默认情况下所有内容都是引用类型。

当您在 C# 参数列表中说“ref”时,您真正所说的更像是“指向指针的指针”。您是说,在方法中,您想要替换的不是对象的内容,而是调用方法的代码中对对象本身的引用。

除非这是您的意图,否则您应该直接传递引用类型;在 C# 中,传递引用类型的成本很低(类似于在 C++ 中传递引用)。

学习/理解 C# 中值类型和引用类型之间的区别。它们是该语言中的一个主要概念,如果您尝试在 C# 领域使用 C++ 对象模型,事情将会变得非常混乱。

以下是本质上语义等效的程序:

#include <iostream>

class AClass
{
    int anInteger;
public:
    AClass(int integer)
        : anInteger(integer)
    {  }

    int GetInteger() const
    {
        return anInteger;
    }

    void SetInteger(int toSet)
    {
        anInteger = toSet;
    }
};

struct StaticFunctions
{
    // C# doesn't have free functions, so I'll do similar in C++
    // Note that in real code you'd use a free function for this.

    static void FunctionTakingAReference(AClass *item)
    {
        item->SetInteger(4);
    }

    static void FunctionTakingAReferenceToAReference(AClass **item)
    {
        *item = new AClass(1729);
    }
};

int main()
{
    AClass* instanceOne = new AClass(6);
    StaticFunctions::FunctionTakingAReference(instanceOne);
    std::cout << instanceOne->GetInteger() << "\n";

    AClass* instanceTwo;
    StaticFunctions::FunctionTakingAReferenceToAReference(&instanceTwo);
    // Note that operator& behaves similar to the C# keyword "ref" at the call site.
    std::cout << instanceTwo->GetInteger() << "\n";

    // (Of course in real C++ you're using std::shared_ptr and std::unique_ptr instead,
    //  right? :) )
    delete instanceOne;
    delete instanceTwo;
}

对于 C#:

using System;

internal class AClass
{
    public AClass(int integer)
        : Integer(integer)
    {  }

    int Integer { get; set; }
}

internal static class StaticFunctions
{
    public static void FunctionTakingAReference(AClass item)
    {
        item.Integer = 4;
    }

    public static void FunctionTakingAReferenceToAReference(ref AClass item)
    {
        item = new AClass(1729);
    }
}

public static class Program
{
    public static void main()
    {
        AClass instanceOne = new AClass(6);
        StaticFunctions.FunctionTakingAReference(instanceOne);
        Console.WriteLine(instanceOne.Integer);

        AClass instanceTwo  = new AClass(1234); // C# forces me to assign this before
                                                // it can be passed. Use "out" instead of
                                                // "ref" and that requirement goes away.
        StaticFunctions.FunctionTakingAReferenceToAReference(ref instanceTwo);
        Console.WriteLine(instanceTwo.Integer);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# ref 是像 C/C++ 中的指针还是 C++ 中的引用? 的相关文章

  • 采用 std::vector 或 std::array 的模板函数

    我有一个函数 当前接受 2 个向量 其中可以包含任何普通的旧数据 template
  • C# 异步任务比同步慢

    你知道为什么同步斐波那契方法比异步 等待更快并且比异步任务更快吗 我在每个项目方法上都使用了异步 所以主要是这是一个非常糟糕的方法 Code static int FibonacciSync int number if number 0 r
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • Qt/c++ 随机字符串生成[重复]

    这个问题在这里已经有答案了 我正在创建一个应用程序 需要生成多个随机字符串 几乎就像一个由一定长度的 ASCII 字符组成的唯一 ID 这些字符混合有大写 小写 数字字符 有没有 Qt 库可以实现这一点 如果没有 在纯 C 中生成多个随机字
  • 如何使用c#从数据桶中获取所有文档?

    如何获取数据桶中的所有文档 我尝试过一个示例 但我只能获得一个特定的文档 这是我的代码 CouchbaseClient oclient oclient new CouchbaseClient vwspace data bucket name
  • C++ 指针和对象实例化

    这有效 MyObject o o new MyObject 而这并不 MyObject o new MyObject Why 关键词new 返回一个指针 http msdn microsoft com en us library kewsb
  • 在 .NET Core 中从 HttpResponseMessage 转换为 IActionResult

    我正在将之前在 NET Framework 中编写的一些代码移植到 NET Core 我有这样的事情 HttpResponseMessage result await client SendAync request if result St
  • 如何调试.NET Windows Service OnStart方法?

    我用 NET 编写的代码仅在作为 Windows 服务安装时才会失败 该故障甚至不允许服务启动 我不知道如何进入 OnStart 方法 如何 调试 Windows 服务应用程序 http msdn microsoft com en us l
  • 模板与非模板类,跨编译器的不同行为

    我在一些应用程序中使用编译时计数器 它确实很有用 昨天我想用 gcc 编译一个程序 我之前使用的是 msvc 并且计数器的行为在模板类中发生了变化 它在模板类中不再工作 过于简化的代码 Maximum value the counter c
  • 检查两个函数或成员函数指针的签名是否相等

    我编写了一些代码来检查自由函数的签名是否等于成员函数的签名等 它比较提取的返回类型和函数参数 include
  • 如何在 C++ 运行时更改 QML 对象的属性?

    我想在运行时更改 QML 对象的文本 我尝试如下 但文本仍然为空 这是后端类 class BackEnd public QObject Q OBJECT Q PROPERTY QString userFieldText READ userF
  • 使用 OleDbCommand / OleDbDataAdapter 读取 CSV 文件

    我不明白为什么 但是当我使用 OleDbDataAdapter 或 OleDbCommand 读取 CSV 文件时 在这两种情况下 生成的数据结构良好 它识别文件头中的列 但行数据都是空字符串 我之前已经成功进行过多次 CSV 处理 因此我
  • linq where 子句和 count 导致 null 异常

    除非 p School SchoolName 结果为 null 否则下面的代码将起作用 在这种情况下 它会导致 NullReferenceException if ExistingUsers Where p gt p StudentID i
  • 如何释放字符串未使用的容量

    我正在程序中处理很多字符串 这些字符串数据在读入我的程序后的整个生命周期内都不会改变 但由于 C 字符串保留了容量 因此浪费了大量肯定不会被使用的空间 我尝试释放这些空间 但没有成功 以下是我尝试过的简单代码 string temp 123
  • 如何在控制台程序中获取鼠标位置?

    如何在 Windows 控制台程序中用 C 获取鼠标单击位置 点击时返回鼠标位置的变量 我想用简单的文本命令绘制一个菜单 这样当有人点击时 游戏就会注册它并知道位置 我知道如何做我需要做的一切 除了单击时获取鼠标位置 您需要使用 Conso
  • 使用任务的经典永无止境的线程循环?

    给出了一个非常常见的线程场景 宣言 private Thread thread private bool isRunning false Start thread new Thread gt NeverEndingProc thread S
  • Unity - 在生成时获取随机颜色

    我有一个小问题 我想在我的场景中生成四边形 它们都应该有红色或绿色作为材质 但 Random Range 函数只能是 int 我该如何解决它 void SpawningSquadsRnd rndColor 0 Color red rndCo
  • Asp.Net Core 中的 SSL 不起作用

    我从 Visual Studio 创建了一个简单的 Web 应用程序Web Application Net Core 具有个人用户帐户授权的模板 然后 我启用了 SSLProject gt MyProject Properties 将带有
  • 在 C# 中使用自定义千位分隔符

    在显示字符串时 我尝试不使用 字符作为千位分隔符 而是使用空格 我想我需要定义一种自定义文化 但我似乎做得不对 有什么指点吗 例如 将 1000000 显示为 1 000 000 而不是 1 000 000 no String Replac
  • 如何通过API退出Win32应用程序?

    我有一个使用 Win32 API 编写的 C Win32 应用程序 我希望强制它在其中一个函数中退出 有没有类似的东西Exit or Destroy or Abort 类似的东西会终止它吗 哎呀呀呀呀呀呀 不要做任何这些事情 exit 和

随机推荐

  • 从 JTabbedPane 中删除蓝色

    这是我第一次使用 JTabbedPane 看起来默认的外观和感觉在选项卡上和组件本身周围显示蓝色边框 我怎样才能禁用该效果 好吧 有一种简单快速的方法可以通过将 LookAndFeel 设置为 SystemLookAndFeel 或任何其他
  • 如何指定使用 bitbake/yocto 构建哪个内核

    我正在努力使用 yocto daisy 生成新的 BSP 当我构建图像时 我收到以下警告 NOTE Resolving any missing task queue dependencies NOTE multiple providers
  • 如何在Android中使用Intent连接已知的WiFi?

    我有这样的事情 wifiNetworks ArrayList
  • 接口错误(0,'')

    我已经使用 Django 构建了一个网站 当我尝试执行查询时 我收到了这个恼人的错误 如果我重新启动 Apache 服务器 该错误将在短时间内消失 Traceback File usr local lib python2 7 site pa
  • Add-ADGroupMember 找不到具有标识的对象

    我正在编写一个 PowerShell 脚本来将大量用户导入到 AD 中 其中一项是根据用户的程序编号将用户添加到 AD 安全组 大多数情况下 这工作得很好 除非我拼写错误 或者其他简单的人为错误 但是 我们有 2 个安全组 每个人都必须添加
  • Prism WPF 动态区域

    假设我们有一个包含模块 A 和 B 的 Prism 7 应用程序 主窗口有一个选项卡控件和两个按钮 用于将模块 A 或 B 添加到选项卡控件 我为选项卡控制项创建了一个绑定 并实现了一个项模板 其中包括 Prism Region 其名称绑定
  • 为什么是$!运算符右结合?

    我刚刚学习 Haskell 我仍然不完全清楚何时以及如何强制进行严格评估 当我想要一个函数严格评估它的参数时 我发现自己在写 f x y z 这看起来很奇怪 不应该 是左关联的 这样我就可以写 f x y z 并让它做我想做的事 我是不是完
  • 如何在 AFNetworking 2.0+ 中使用 AFHTTPRequestOperationManager 使用 cookie?

    众所周知 AFHTTP会话管理器AFNetworking 2 0 支持cookie 但有可能吗AFHTTP请求操作管理器在 AFNetworking 2 0 中支持 cookie 是的 AFNetworking 使用基础 URL 加载系统
  • 在python中创建v7.3的.mat文件

    我需要在 python 或 matlab 中执行涉及 60000X70000 矩阵的乘法 我有 16GB RAM 能够轻松加载矩阵的每一行 这就是我所需要的 我可以在 python 中创建整个矩阵 但不能在 matlab 中创建 无论如何
  • TypeScript - 将子类转换为超类

    下面的问题有简单的解决办法吗 我想将对象 B 转换为对象 A 感谢您的解决方案 export interface A a string export interface B extends A b string const b B a te
  • 类型错误:当我尝试识别照片时,“元组”对象无法解释为整数

    我想测试训练好的模型 我使用keras和opencv 代码如下 创建参数解析器并传递它们 ap argparse ArgumentParser ap add argument i image required True help path
  • 从包含 100,000 个整数的列表中检索两个最高的项目

    如何从包含 100 000 个整数的列表中检索两个最高的项目 而不必先对整个列表进行排序 Use heapq nlargest http docs python org library heapq html heapq nlargest 如
  • 选择多个字段分组依据和总和

    我想用 linq 对象列表 进行查询 但我真的不知道该怎么做 我可以进行组和求和 但无法选择其余字段 例子 ID Value Name Category 1 5 Name1 Category1 1 7 Name1 Category1 2 1
  • Angular 2 ngOnInit 中的测试承诺

    我有一个 Angular 2 组件 我试图对其进行测试 但我遇到了麻烦 因为数据设置在ngOnInit函数 因此不能立即在单元测试中使用 用户视图 component ts import Component OnInit from angu
  • VBA Internet Explorer 自动化 - 下载文件时如何选择“打开”

    这是我在 stackoverflow 上遇到的第一个问题 我一直在寻找这个问题的解决方案一段时间 但没有找到任何帮助 我可能只是在搜索中使用了错误的关键字 但到目前为止我还没有运气 这是问题 在 VBA 中 如何从 Internet Exp
  • Mongoose findoneandupdate 返回更新的文档但未在数据库中更新

    架构是正确的 这些字段应该更新 因此 我从一次 API 调用中获取了部分数据 还有一些来自另一个 我将在下面注明 我的架构 var coin new Mongoose Schema id Number rank Number source
  • 带有多个提交按钮的表单的 Javascript onsubmit

    我有一个带有两个提交按钮的表单 一个称为 显示 另一个称为 取消注册 显示提交不需要确认 而其他则需要确认 本来我打算用 onsubmit return confirm Are you sure you want to remove the
  • 在matlab中求解矩阵方程

    我有一个类型的方程c Ax By where c x and y是维度为 50 000 X 1 的向量 并且A and B是维度为 50 000 X 50 000 的矩阵 Matlab有没有办法求矩阵A and B when c x and
  • 如何根据条件限制并发消息消耗

    场景 我已经简化了事情 许多最终用户可以从前端 Web 应用程序 生产者 开始工作 繁重的工作 例如渲染大型 PDF 这些作业被发送到单个持久的 RabbitMQ 队列 许多工作应用程序 消费者 处理这些作业并将结果写回到数据存储中 这个相
  • C# ref 是像 C/C++ 中的指针还是 C++ 中的引用?

    我正在与ref并且不太明白 它像 C C 中的指针还是 C 中的引用 为什么我会问你这么弱的问题 因为 当我阅读 C NET 书籍 msdn 或与 C 开发人员交谈时 我对以下原因感到困惑 C 开发者建议不要使用ref在函数的参数中 e g