c# - c# 中 `this` 和 `ref` 的等效功能
问题描述
如果我在一个类中有一个函数:
/* class snipped */
private void Expect(ref Utf8JsonReader reader, JsonTokenType t)
{
reader.Read();
/* snip */
}
由于正在操作对象,因此通过引用传递,这与静态辅助函数有什么不同:
/*static class snipped*/
static public void Expect(this Utf8JsonReader reader, JsonTokenType t)
{
reader.Read();
/* snip */
}
// call helper via reader.Expect(requiredToken)
我问如果在使用时有任何看不见的细微差别ref
,它大量存在于代码旁边Utf8JsonReader
,并且Memory<T>
对象在嵌套函数之间传递。
我正在寻找重构(在这种情况下,在阅读器对象上使用扩展方法会更好)。
this
(外部类的扩展方法)和ref
(函数之间的引用传递)在功能上是否等效?
更新 -ref this
需要??
作为更新,简单地使用this
不起作用,在ExpectNamedProperty
它会调用的函数内reader.Expect
但在返回对象时会恢复。不知何故,正在堆栈上制作副本或正在发生某些事情。
我什至不知道这是一个有效的组合,ref this
确实有效,而this
只是不修改。需要澄清不做可怕的事情!
public static void Expect(ref this Utf8JsonReader reader, JsonTokenType t)
{
reader.Read(); // this mutation is never passed back to caller
}
public static void ExpectNamedProperty(ref this Utf8JsonReader reader, string expectedPropertyName)
{
reader.Expect(JsonTokenType.PropertyName, expectedPropertyName);
// at this point it is as if the function above was never called
var foundPropertyName = reader.GetString();
if (foundPropertyName != StreamFieldNames.Event)
throw new JsonException($"expected {StreamFieldNames.Event} found {foundPropertyName} at position {reader.Position.GetInteger()}");
}
解决方案
你可以写很多扩展方法,但它们真的相关吗?在扩展方法中编写所有内容都会生成意大利面条式代码。
我会选择in
关键字。in
over的优点ref
是您无法修改参数,但不会获得副本(如“正常”参数)。您也可以将只读字段作为in
参数传递。
private void Expect(in Utf8JsonReader reader, in JsonTokenType t)
{
reader.Read();
/* snip */
}
推荐阅读
- powershell - 为什么数学运算符没有用正确的值四舍五入。?
- ios - 无法在 iOS 上为流式传输设置 360p 视频设置
- angular - 如何仅向路由器出口显示 ngx 加载动画?
- php - php正则表达式忽略“S”字符
- android - 带有 websocket 的 Expo v27/v28 Android 应用程序崩溃
- docker - 我可以通过内部 url 访问 docker 启动的服务吗?
- c++11 - C++:如何使用 lldb 调试“总线错误”?
- java - 选择项目时,Spinner 的 OnItemSelectedListener 不调用
- sql - 为什么“=”运算符在 SQL 查询中没有给出预期的结果?
- javascript - 将 SVG 组件作为背景图像反应到 div