【问题标题】:Passing a literal with the "in" parameter modifier使用“in”参数修饰符传递文字
【发布时间】:2020-03-13 18:22:12
【问题描述】:

目前尚不清楚为什么 C# 不允许调用与 in 参数修饰符一起传递文字的方法;同时,当文字传递给没有in 参数修饰符的方法时,代码编译。

这是一个演示此行为的代码示例 (C# 7.3):

class Program
{
    static void Main(string[] args)
    {
        string s = string.Empty;

        //These two lines compile 
        WriteStringToConsole(in s);
        WriteStringToConsole("my string");

        //Error CS8156  An expression cannot be used in this context because it may not be passed or returned by reference 
        WriteStringToConsole(in "my string");
    }

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

【问题讨论】:

  • in 关键字导致参数通过引用传递。它使形参成为实参的别名,实参必须是变量。
  • @GoodSamaritan 您应该在评论中添加您引用的链接。
  • 调用方法中不需要“in”。方法声明中只需要它。
  • “in”的唯一含义是,防止传递文字和属性。如果您不想阻止它,请不要使用它。

标签: c#


【解决方案1】:

正如C# language reference 中所指定的,您不能使用带有in 关键字的常量作为参数:

与 in 一起使用的参数必须表示可以直接引用的位置。 out 和 ref 参数适用相同的一般规则:您不能使用常量、普通属性或其他产生值的表达式。

【讨论】:

    【解决方案2】:

    在 C# 7.2 中,引入了“in parameter”,它允许传递变量的只读引用。在 C# 7.2 之前,我们使用“ref”和“out”关键字来传递变量的引用。 “Out”仅用于输出,而“ref”用于输入和输出。但是,如果我们必须传递一个只读引用,即只传递一个变量作为输入,那么就没有直接的选择。因此,在 C# 7.2 中,为此目的引入了“in parameter”

    你可以参考下面的答案正确使用in参数

    https://stackoverflow.com/a/52825832/3992001

           static void Main(string[] args)
            {
                WriteStringToConsole("test"); // OK, temporary variable created.
                string test = "test";
                WriteStringToConsole(test); // OK, temporary int created with the value 0
                WriteStringToConsole(in test); // passed by readonly reference, explicitly using `in`
                //Not allowed
                WriteStringToConsole(in "test"); //Error CS8156  An expression cannot be used in this context because it may not be passed or returned by reference
    
            }
            static void WriteStringToConsole(in string argument)
            {
                Console.WriteLine(argument);
            }
    

    【讨论】:

      【解决方案3】:

      很清楚为什么在使用in 参数修饰符调用方法时不能将in 修饰符与文字一起使用; refout 修饰符也不允许这样做:

      in parameter modifier (C# Reference)

      in 一起使用的参数必须表示一个可以被 直接提到。 outref 参数的一般规则相同 apply:不能使用常量、普通属性或其他 产生值的表达式。

      当您想将不带in 修饰符的文字传递给带有in 参数修饰符的方法时,编译器会创建一个临时变量并使用对该变量的引用来调用该方法。这样做的原因如下:

      in parameter modifier (C# Reference)

      在调用站点省略 in 会通知编译器您将允许 它创建一个临时变量以通过只读引用传递给 方法。 编译器创建一个临时变量来克服 in 参数的几个限制

      • 临时变量允许编译时常量作为in 参数。
      • 临时变量允许in 参数的属性或其他表达式。
      • 临时变量允许参数 从参数类型到参数类型的隐式转换。

      总而言之,这两个选项都是允许的,因为它们每个都有不同的用例,但最终还是对变量的只读引用。

      【讨论】:

        猜你喜欢
        • 2018-08-24
        • 2021-09-11
        • 2019-03-20
        • 2018-11-19
        • 2020-03-26
        • 1970-01-01
        • 1970-01-01
        • 2023-02-25
        相关资源
        最近更新 更多