【问题标题】:What's the difference of passing a class as a normal parameter and by reference?将类作为普通参数传递和通过引用传递有什么区别?
【发布时间】:2013-08-07 08:11:32
【问题描述】:

以一个简单的方法为例:

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);
}

这里的主要区别是什么?

【问题讨论】:

  • ByRef 只指向对象(例如,当您想要填充属性时,在 subs 中非常有用),ByVal 复制对象,使其成为对象的新实例。

标签: c# ref


【解决方案1】:

在您的具体示例中,没有区别,因为您没有为参数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
        }
    }
}

【讨论】:

    【解决方案2】:

    区别在于:

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

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

    • 1234563 /li>

    (最后一点不受规范规定,但这是实际实现如何处理ref 参数。规范仅说明参数应该如何工作,而不是应该如何实现。)

    【讨论】:

    • 不列出实现细节,引用类型也有2错。
    猜你喜欢
    • 2015-08-27
    • 2023-03-23
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 2012-07-26
    • 2012-05-22
    • 1970-01-01
    • 2011-08-21
    相关资源
    最近更新 更多