【问题标题】:Returning parameter instead of passing it by Ref [duplicate]返回参数而不是通过 Ref [重复]
【发布时间】:2020-03-28 03:22:20
【问题描述】:

我有时看到有一个参数的方法,修改它并返回它。 这样做有什么好处,为什么不简单地通过 ref 传递参数并通过ref 保留方法?

这是我看到的:

public MyClass DoSomething(MyClass myClass)
{
    myClass.Amount = 500;
    return myClass;
}

为什么不保持简单:

public void DoSomething(ref MyClass myClass)
{
    myClass.Amount = 500;
}

【问题讨论】:

  • ref MyClass myClass 如果 myClass 是一个类就没有多大意义,如果 myClass 是一个结构体就有意义。
  • 第二种方法不需要加ref。
  • @StefanoBalzarotti 实际上,如果您想覆盖实例,ref 是有意义的。
  • 这是 Jon Skeet 的一篇不错的博客,其中介绍了引用类型以及它与通过引用传递的区别 jonskeet.uk/csharp/parameters.html
  • 是的,这样您就可以将它们链接起来:MyClass x = myClass.DoSomethingA ().DoSomethingB ().DoSomethingC () - 但是请注意,如果方法在类中,则没有理由将实例作为参数提供...除非它是静态扩展方法。

标签: c#


【解决方案1】:

如果MyClass 是下面示例中的引用类型

public MyClass DoSomething(MyClass myClass)
{
    myClass.Amount = 500;
    return myClass;
}

返回它没有意义,因为所有引用类型都是通过引用传递的,你可以做类似的事情

public void DoSomething(MyClass myClass)
{
    myClass.Amount = 500;
}

仅当MyClass 是值类型(继承struct)时才有意义。

但是,.NET Core 中引入了新类型ref structs,它用于在堆栈中分配struct 类型并通过引用而不是通过值传递它们(无需复制)。你可以阅读documenation

【讨论】:

  • 实际上像这样返回对象对于将调用链接在一起很有用,
  • 是的,某种流畅的API,但是OP没有提到这一点
【解决方案2】:

仅当您打算更改参数的引用时,使用 ref 关键字才有意义。一般来说,您希望避免这种情况,但如果您觉得必须这样做:

public class MyClass 
{
    public int Id { get; set; }
    public int Amount { get; set; }
}

假设 myClass 参数有Id = 1Amount = 300

这行得通:

public void DoSomething(MyClass myClass) 
{
    myClass.Amount = 500;
}

myClass.Amount 已变为500

这不起作用:

public void DoSomething(MyClass myClass) 
{
    myClass = new MyClass()
    {
         Id = 5,
         Amount = 500
    }
}

myClass.Amount 仍然是 300myClass.Id1

但是,这确实有效:

public void DoSomething(ref MyClass myClass) 
{
    myClass = new MyClass()
    {
         Id = 5,
         Amount = 500
    }
}

myClass.Amount500myClass.Id5

【讨论】:

    【解决方案3】:

    如前所述,如果MyClass 是引用类型,则ref 没有多大意义。

    但是返回传递的参数是有意义的,因为它返回显式修改的参数,所以它适用于结构和类。并且更具可读性,这是非常好的事情。

    另外,如果我们谈论引用类型,ref 是不必要的,没有它的代码更简洁。

    【讨论】:

    • 实际上,如果你想允许方法用一个新的对象覆盖整个对象,这是有意义的。
    猜你喜欢
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    相关资源
    最近更新 更多