什么';s将类作为普通参数和通过引用传递的区别

本文关键字:参数 引用 区别 什么 | 更新日期: 2023-09-27 18:26:39

以一个简单的方法为例:

public string GetDisplayName(string username, IUserService UserService)
{
    var user = UserService.GetUserByUsername(username);
    return string.Format("{0} {1} {2} ({3})", user.Title, user.FirstName, user.LastName, username);
}

所以UserService是一个类,根据C#中的定义,类是一个引用类型。

如果我要做以下操作:

public string GetDisplayName(string username, ref IUserService UserService)
{
    var user = UserService.GetUserByUsername(username);
    return string.Format("{0} {1} {2} ({3})", user.Title, user.FirstName, user.LastName, username);
}

这里的主要区别是什么?

什么';s将类作为普通参数和通过引用传递的区别

在您的特定示例中,没有任何区别,因为您没有为参数UserService赋值。

但是,如果要为UserService参数分配一个新实例,则会更改该方法的调用者引用的对象。

下面是一个演示差异的示例程序:

using System;
namespace Demo
{
    class Demo
    {
        public int Value;
        public Demo(int value)
        {
            Value = value;
        }
    }
    class Program
    {
        private static void test1(Demo demo)
        {
            demo = new Demo(42);
        }
        private static void test2(ref Demo demo)
        {
            demo = new Demo(42);
        }
        private static void Main()
        {
            Demo demo1 = new Demo(0);
            Demo demo2 = demo1; // demo2 references demo1.
            // Calling test1() will NOT change the object referenced by demo1:
            test1(demo1);
            Console.WriteLine(demo1.Value); // Prints 0
            demo2.Value = 1;
            Console.WriteLine(demo1.Value); // Prints 1, indicating that changing demo2 also changed demo1
            // Calling test2() will cause demo1 to reference a DIFFERENT instance of class Demo:
            test2(ref demo1);
            Console.WriteLine(demo1.Value); // Prints 42, indicating that demo1 was changed.
            demo2.Value = 1;
            Console.WriteLine(demo1.Value); // Prints 42, indicating that changing demo2 no longer changes demo1
        }
    }
}

区别在于:

  • 带有ref参数的方法需要使用该参数的变量进行调用。例如,如果要使用new CompanyUserService()为调用创建用户服务,则需要将其放入变量中,并在调用中使用该变量,而不是仅传递新创建的引用。

  • 在带有ref参数的方法内部,可以更改调用中使用的变量的值。在另一种方法中,参数是值的副本,因此在方法内部更改参数变量的值不会影响方法外部的任何内容。

  • 带有ref关键字的参数作为指针发送到包含值的变量,而不是值本身,因此无论何时在方法中使用该参数,都会有另一个重定向步骤。

(最后一点不是由规范决定的,而是实际实现如何处理ref参数。规范只说明了参数应该如何工作,而不是应该如何实现。)