【问题标题】:Is there any advantage with the "in" keyword on reference types?引用类型上的“in”关键字有什么优势吗?
【发布时间】:2019-03-11 15:37:28
【问题描述】:

我只是好奇,将in 关键字用于引用类型参数(如string)有什么好处吗?

示例:

bool IsNice(string greeding)
{
    return greeding.Contains(":-)");
}

VS

bool IsNice2(in string greeding)
{
    return greeding.Contains(":-)");
}

【问题讨论】:

  • 否;如果有轻微的性能损失,我不会感到惊讶
  • in 的主要优点是对于大值类型;我唯一希望看到带有引用类型的inin T someValue 对于一些T 在通用<T> 类型/方法中,而T 原来是一个引用-有时输入

标签: c# performance keyword


【解决方案1】:

在性能方面,可能不多。您正在添加额外的取消引用。

获取代码

public class C
{
    public void WithoutIn(string s)
    {
        Console.WriteLine(s);
    }

    public void WithIn(in string s)
    {
        Console.WriteLine(s);
    }
}

这被认为是:

C.WithoutIn(System.String)
    L0000: mov ecx, edx
    L0002: call System.Console.WriteLine(System.String)
    L0007: ret

C.WithIn(System.String ByRef)
    L0000: mov ecx, [edx]
    L0002: call System.Console.WriteLine(System.String)
    L0007: ret

(SharpLab)。

唯一的区别是mov ecx, [edx] 而不是mov ecx edx。我想这种取消引用会稍微减慢速度,但不会有任何可观察的量。

实际上,这意味着你不能这样做:

public void M(in string s)
{
    s = "foo"; // CS8331: Cannot assign to variable 'in string' because it is a readonly variable
}

in 被添加到语言中以增强对通过引用传递结构的支持。我会质疑任何将它与引用类型一起使用的代码:我假设它是由于值类型后来更改为引用类型的结果,而不是因为某些深思熟虑的决定。

【讨论】:

  • 感谢所有答案,我将其标记为显示和解释 CIL 的解决方案,并指出,与大多数预期相反,引用类型上的 IN 关键字可能使其更慢!
  • @Marc 谢谢!请注意,这是汇编,而不是 CIL。
【解决方案2】:

来自“In Parameters in C# 7.2 – Read-only References”:

C# 中的 In 参数类似于 ref 参数,只是它们在方法内是只读的。而且,它们不能进一步修改。你只能参考他们。

所以只读?

【讨论】:

  • 请注意,这只是意味着您不能分配给引用 - 您可以对其进行变异。
  • @canton7 字符串不是不可变的吗?
  • @UweKeim 字符串是,但其他引用类型可能不是。 OP 的问题是关于所有引用类型,string 只是一个例子
  • 它是一个只读引用,对值类型有一些额外的行为。在这种情况下,这并不会真正产生影响。
  • 如果值类型参数具有in 限定符,编译器将如何处理实例方法和属性: (1) 不允许使用它们; (2) 允许它们,并传递结构的副本,或者 (3) 允许它们,并传递实际的结构?
【解决方案3】:

两者的行为不同。

在第二个示例中,对您通过引用传递的变量所做的任何更改都将被该方法观察到。

在第一种情况下,您没有传递变量,而只是传递了一个值。如果您通过获取变量的值来获得该值,那么之后对该变量的任何更改都不会被观察到。

在对方法的初始调用之后更改变量将相当困难,因此我不希望它在实践中经常发生,但这是可能的。

【讨论】:

    猜你喜欢
    • 2010-12-14
    • 2014-11-13
    • 1970-01-01
    • 2014-06-21
    • 2014-11-25
    • 2020-10-02
    • 2016-01-09
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多