【问题标题】:How can I avoid ref parameters?如何避免 ref 参数?
【发布时间】:2012-02-27 18:45:30
【问题描述】:

我有一个有 2 个 ref 参数的方法:

public void ReplaceSomething(ref int code, ref string name)
{
    ...
}

我想避免这种情况,因为它不是一个好的设计(而且扩展性很差)。我有哪些选择?

我曾考虑过使用匿名对象,但这似乎也不是一个好主意。

Object something = new { code = 1, name = "test" };

ReplaceSomething(something);

【问题讨论】:

  • 为什么要避免引用参数?参考参数有其用途,应在需要时使用。
  • ReplaceSomething 是做什么的,为什么它现在使用 ref 参数?
  • stackoverflow.com/questions/3539252/… 我只是在寻找另一种方法来做到这一点,基于这个主题。
  • @Hor - 这个问题并不能解释你试图避免 ref 参数的原因。
  • 首先,参数真的是ref吗?他们应该是out吗?

标签: c# pass-by-reference anonymous


【解决方案1】:

代码和名称是否紧密联系在一起?如果是这样,请考虑创建一个类型来将它们两个放在一起。然后您可以返回该类型的值。

或者,您可以考虑返回Tuple<int, string>

(当然,在这两种情况下,您都可以接受相同类型的输入参数。由于您没有显示任何代码,因此不清楚您是否使用参数的现有值,或者它们是否可以基本上都是out参数。)

【讨论】:

  • 作者没有说明他使用的是哪个版本的 .NET,这对于 Tuple 解决方案当然很重要。你知道,但其他人可能不知道。
  • @Andrew,但在旧版本的框架上创建自己的 Tuple 很简单。
  • 这个元组非常棒!非常感谢!我现在就去读!
【解决方案2】:

为什么不想使用ref 参数?这似乎是更改某些调用者值的绝佳方式。

另一种方法是实现返回值。也许您需要更好地解释问题所在?

【讨论】:

  • 我刚刚在这里看到这不是一个好方法。 stackoverflow.com/questions/3539252/…
  • @Hor:我明白了。他的主要观点是,他似乎不喜欢ref 的模棱两可,而是更喜欢out,这要求参数总是由方法更新。我认为ref 很好,但实际上,如果您总是更新参数值,那么请改用out
【解决方案3】:

如果这些值紧密耦合并且“属于一起”,您可以定义一个自定义类来保存您的属性,然后返回一个新实例(假设其不可变)或更新其属性:

class Code
{
  public int Value {get;set;}
  public string Name {get;set;}
}

public Code UpdateCode(Code code)
{
    ...
}

【讨论】:

    【解决方案4】:

    如果需要返回这些值,可以使用元组

    public Tuple<int, string> ReplaceSomething(int code, string name)
    {
        ...
    }
    

    或者创建您自己的类包装器,将值作为属性保存

    public Foo ReplaceSomething(int code, string name)
    {
        var foo = new Foo(){...};
        return foo;
    }
    
    class Foo
    {
        public int IntValue{get;set;}
        public string StringValue{get;set;}
    }
    

    【讨论】:

    • 我认为作者的观点是,这些值实际上确实需要以某种方式返回。
    • 但是当我改变它们时我需要返回值,这就是我通过引用传递的原因。在不创建全局变量或通过引用传递的情况下,还有其他方法吗?
    【解决方案5】:

    你为什么要改变它? ref 参数有时是有意义的,如果这是其中之一 - 使用它们。您可以引入一个包含该对值的新类,这只有在这些值经常组合在一起时才有意义。

    我说,保留它。

    【讨论】:

      【解决方案6】:

      根据你的问题,我可能会离开。替换 ref 是什么意思?你想超载吗?

      public void ReplaceSomething(int code, string name)
      {
          // ...
      }
      
      public void ReplaceSomething()
      {
          return ReplaceSomething(1, "test");
      }
      

      编辑:

      好的,所以你需要返回codename 需要进行哪些计算? Jon Skeet 关于元组的回答可能是正确的,或者您可能需要一个包含 codenamereplaced 的 POCO

      public void ReplaceSomething(int code, string name)
      {
          var replaced = new Replaced();
          replaced.code = code;
          replaced.name = name;
      
          var r;
          // do some replacement calculations
          replaced.replaced = r;
      
          return replaced;
      
      }
      
      public class Replaced {
          public string name {get; set;}
          public int code {get; set;}
          public string replaced {get; set;}
      }
      

      【讨论】:

      • 但是当我改变它们时我需要返回值,这就是我通过引用传递的原因。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多