错误“参数是值而参数声明为 in”是什么意思?

Kzr*_*tof 4 c# .net-core .net-standard-2.0

netstandard 2.0应用程序中,我有以下方法是静态类的一部分:

public static class Argument 
{    
    /// <param name="inst">Inst.</param>
    /// <param name="instName">Inst name.</param>
    /// <exception cref="ArgumentException">
    /// Thrown if :
    /// <paramref name="inst" /> is not specified in a local time zone.
    /// </exception>
    public static void ThrowIfIsNotLocal(in DateTime inst, string instName)
    {
        if (inst.Kind != DateTimeKind.Local)
            throw new ArgumentException(instName, $"{instName} is not expressed in a local time-zone.");
    }
}
Run Code Online (Sandbox Code Playgroud)

在我正在运行的程序中.netcore 2.0,我有以下生成错误的行:

Argument.ThrowIfIsNotLocal(DateTime.Now, "timestamp");
Run Code Online (Sandbox Code Playgroud)

参数是值,而参数声明为

为什么会DateTime.Now导致错误出现?

Ser*_*rvy 5

方法签名指出参数需要通过引用传递,而不是通过值传递。这意味着您需要有某种存储位置可以被引用以传递到该方法中。

属性 getter 的结果不是变量;这不是你可以参考的东西。它只是一个值,因此是错误消息。

您需要有一个变量,而不仅仅是一个值,并且in在调用方法时还需要使用关键字来指示您打算传递对变量的引用,而不仅仅是变量的值。

var now = DateTime.Now;
ThrowIfIsNotLocal(in now, "");
Run Code Online (Sandbox Code Playgroud)

当然,首先没有真正的理由通过引用传递这个变量。我建议不要这样做,而只是按值传递参数。这样当调用者只有一个值而不是一个变量时,他们就不需要经历所有这些。

  • @Kzrystof 1) 这涉及比引用大得多的类型 2) 基准测试涉及返回一个从未使用过的值,因此理论上可以完全省略整个事情。这不是一个有意义的基准。同样,您的代码涉及一个不大于引用的类型,并且考虑到调用者显然并不总是已经有一个变量,这意味着他们正在做一个副本*无论如何*,把它放在一个变量中(否则就不需要)只是为了这个方法的目的。我没有说使用 `in` 是*从不* 的,只是它不*在这里*。 (3认同)
  • @Kzrystof 那篇文章的后半部分是他们谈论他们创建任何导致性能差异的示例有多困难,这也毫无价值。这应该让你知道这不是你只是在你拥有的每个参数上拍打的东西,而是针对*非常特定*情况的东西。 (2认同)