如何使用 in 参数直接调用带有 ref 参数的方法
How to directly call a method with ref parameter using in parameter
我正在使用旧库中的方法:F (ref T t) where T: struct
。仅出于性能原因将其声明为 ref
,并且不会修改它接收到的数据。此库无法更改。
在我的代码中,我有一个调用 F
.
的新方法 G (in T t) where T: struct
有没有一种方法可以直接使用我收到的参考调用 F
而无需先将其复制到临时文件?
我刚刚阅读了 "in"。显然,in、ref 和 out 都是引用调用的一种形式。然而,主要区别是 "their statement of intent".
in
参数无法修改。如果有的话,它们只是出于性能原因的参考。
ref
参数可以修改也可以不修改。它最接近经典"call by reference"。事实上,这是您通过裸指针实现它时获得的唯一方法
out
个参数 有 个要修改;如果一个值需要初始化(比如构造函数中的只读),这可能是相关的 - 如果它作为输出变量提交,编译器可以放心它 将 被设置。其他函数编译器确保了这一点。
在某种程度上 in
是一种 "ref, but readonly"。无法将收到的 "in" 分配给 "ref" 或 "out" 以及阻止您 意外地 更改值。我想你也不会在那里使用 ref(这可能毫无意义)或进行复制。
是的,有办法(但它使用了不安全的黑魔法)。
首先是免责声明。
方法 F
不修改 struct
的事实只是你的 "convention"。对于 C# 编译器,ref
提供的 struct
是完全可变的。
readonly ref
通过 in
提供的 struct
告诉编译器:请确保这个 struct
不能被改变。
顺便说一句,如果您将 struct
作为 in
传递,您 必须 确保此 struct
被声明为readonly struct
。否则,编译器将创建 struct
的防御性副本(有关详细信息,请阅读 here。)这是您 通常 无法传递 [=23] 的第二个原因=] 引用通过 ref
接受 struct
并对其进行变异的方法。
如果您仍想解决所有这些限制,可以使用 System.Runtime.CompilerServices.Unsafe
NuGet 包。
Unsafe
静态class中有一个方法可以帮助你:
public static ref T AsRef<T>(in T source);
这是一个例子:
void F<T>(ref T t) where T : struct
{
}
void G<T>(in T t) where T : struct
{
F(ref System.Runtime.CompilerServices.Unsafe.AsRef(in t));
}
我正在使用旧库中的方法:F (ref T t) where T: struct
。仅出于性能原因将其声明为 ref
,并且不会修改它接收到的数据。此库无法更改。
在我的代码中,我有一个调用 F
.
G (in T t) where T: struct
有没有一种方法可以直接使用我收到的参考调用 F
而无需先将其复制到临时文件?
我刚刚阅读了 "in"。显然,in、ref 和 out 都是引用调用的一种形式。然而,主要区别是 "their statement of intent".
in
参数无法修改。如果有的话,它们只是出于性能原因的参考。
ref
参数可以修改也可以不修改。它最接近经典"call by reference"。事实上,这是您通过裸指针实现它时获得的唯一方法
out
个参数 有 个要修改;如果一个值需要初始化(比如构造函数中的只读),这可能是相关的 - 如果它作为输出变量提交,编译器可以放心它 将 被设置。其他函数编译器确保了这一点。
在某种程度上 in
是一种 "ref, but readonly"。无法将收到的 "in" 分配给 "ref" 或 "out" 以及阻止您 意外地 更改值。我想你也不会在那里使用 ref(这可能毫无意义)或进行复制。
是的,有办法(但它使用了不安全的黑魔法)。
首先是免责声明。
方法 F
不修改 struct
的事实只是你的 "convention"。对于 C# 编译器,ref
提供的 struct
是完全可变的。
readonly ref
通过 in
提供的 struct
告诉编译器:请确保这个 struct
不能被改变。
顺便说一句,如果您将 struct
作为 in
传递,您 必须 确保此 struct
被声明为readonly struct
。否则,编译器将创建 struct
的防御性副本(有关详细信息,请阅读 here。)这是您 通常 无法传递 [=23] 的第二个原因=] 引用通过 ref
接受 struct
并对其进行变异的方法。
如果您仍想解决所有这些限制,可以使用 System.Runtime.CompilerServices.Unsafe
NuGet 包。
Unsafe
静态class中有一个方法可以帮助你:
public static ref T AsRef<T>(in T source);
这是一个例子:
void F<T>(ref T t) where T : struct
{
}
void G<T>(in T t) where T : struct
{
F(ref System.Runtime.CompilerServices.Unsafe.AsRef(in t));
}