如何在C#方法中返回两个值

4
我在我的项目中创建了一个 C# 函数来比较价格。
public static decimal? SpecialPrice(decimal w, decimal p)
{
    if (w < p)
    {
        return p;
    }
    else if (w > p && p > 0)
    {
        //return (w , p);
    }
    else
    {
        return w;
    }
}

当w > p且p >0时,我希望能够返回两个变量(w和p),但我不知道如何这样返回。有人知道吗?


4
请为您的花括号选择一种风格,并保持一致。 - Steve Wellens
2
可能是一个函数是否可以返回两个值?的重复问题。 - Jon Hanna
关于这个逻辑令人困惑的是,如果将wp作为输入和输出参数来处理。 - John Alexiou
8个回答

9

将多个值返回给调用代码的选择如下:

  1. Out参数
  2. Ref参数
  3. 返回包含多个值或其他类型(例如集合)的结构体/对象

基本上,#1和#2让您拥有方法参数,可以将值传递回调用代码。请参见此处的示例和参考文献:

http://msdn.microsoft.com/en-us/library/ee332485.aspx (out参数)

http://msdn.microsoft.com/en-us/library/14akc2c7.aspx (ref参数)

对于#3,您需要使用与 decimal?不同的返回值。例如,您可以声明一个具有两个属性的类并返回该实例。或者返回List<decimal>或其他可以容纳多个值的类型。

我不太清楚您的代码意图是什么,因此您需要决定哪种方法最适合您。


7

在C#中,方法无法返回两个值。最好是返回一个数组或一些集合类型,这样可以存储多个值。

可能像这样:

public static decimal[] SpecialPrice(decimal w, decimal p)
{
   if (w < p)
   {
      return new decimal[] { p };
   }
   else if(w > p && p > 0)
   {
       return new decimal[] { w, p };
   }
   else
   {
       return new decimal[] { w };
   }
}

如果在执行此方法后了解每个值的含义很重要,可以使用更复杂的集合类,如Dictionary类,它可以让您通过名称引用其每个值。
在这种情况下,我不会创建新的结构体或类,因为我认为数组大小是返回多少值的一个非常明显的指示,而使用类和结构体在调用此方法之前和之后将具有相同数量的变量,使得很难确定返回了多少个值。

使用集合初始化程序时,指定数组大小是多余的(除非您希望在意外指定错误数量的项目时获得编译错误)。 - Kevin Stricker
@mootinator,你可能是对的。我只是写了这个而没有测试。我会进行更正。 - Roman
2
@socheata:你真的不需要在每个回答下留下“+1谢谢你的回答”的评论。只需点击+1按钮,他们就能知道自己的回答已被投票支持。在这里,假设这意味着“谢谢,这个答案很有用”。随处添加这样的评论只会让事情变得混乱。 - Cody Gray

7

你可以使用一个Tuple

public static Tuple<decimal?, decimal?> SpecialPrice(decimal w, decimal p)
{
   if (w < p)
   {
      return new Tuple<decimal?, decimal?>(p, null);
   }
   else if(w > p && p>0)
   {
      return new Tuple<decimal?, decimal?>(p, w);
   }
   else
   {
      return new Tuple<decimal?, decimal?>(w, null);
   }
}

Tuple.Create(p, (decimal?)null); 会稍微简洁一些。 - Kevin Stricker
@plmw:我尝试过了,但结果包含了(,),我该如何避免这种格式并显示结果? - Nothing
@socheata 你想使用.ToString()来显示价格吗?如果是的话,你应该使用tuple.Item1.ToString()来选择第一个值。但是,当你同时返回w和p时,你想要显示什么? - plmw
我想要在w上加删除线并显示p。 - Nothing
@socheata 然后将 w 和 p 交换位置(我已在我的答案中进行了编辑),始终打印第一个项目:tuple.Item1,如果 tuple.Item2 != null,则使用删除线打印出来。 - plmw

1

尝试使用 KeyValuePair<decimal,decimal>(w,p),但需要将返回类型更改为 KeyValuePair

希望能对你有所帮助。


1

这就是为什么结构体被发明出来的原因

public struct PricePoints
{
    decimal? w, p;

    public PricePoints SpecialPrice()
    {
        PricePoints res;
        if (w < p)
        {
            res.p = p;
            res.w = null;
        }
        else if (w > p && p > 0)
        {
            res = this;
        }
        else
        {
            res.w = w;
            res.p = null;
        }
        return res;
    }
}

1

你不能让它返回多个对象。但是,你可以让你返回的对象更加复杂。

public struct PandW
{
   public decimal? p{get;set;}
   public decimal? w{get;set;}
}

然后将您的方法更改为返回PandW对象:

 public static PandW SpecialPrice(decimal w, decimal p)
 {
 PandW temp;
if (w < p)
{
  temp.w=null;
  temp.p=p;
  return temp;
}else if(w > p && p>0){
   temp.w=w;
  temp.p=p;
  return temp;
}else{
   temp.w=w;
   temp.p=null;
   return temp;
}

}


1

有几种方法可以返回多个值:

  • 您可以创建一个带有多个字段的类或结构,并从您的方法返回一个实例
  • 您可以向您的方法添加输出参数
  • 您可以返回一个数组
  • 您可以返回一个 KeyValuePair(不建议)

在这种特定情况下,我更喜欢使用第一种方法返回两个值:

class PriceRet {
    decimal? w;
    decimal? p;
}
PriceRet SpecialPrice(decimal w, decimal p) {
    var res = new PriceRet();
    if (w < p) {
        res.p = p;
    } else if(w > p && p>0) {
        res.w = w;
        res.p = p;
    } else {
        res.w = w;
    }
    return res;
}

0

最好的方法是返回具有两个属性的对象,您也可以使用out变量

public static testhelper SpecialPrice(decimal w,decimal p)
{

//set your values in the object 
var Obj=new testhelper{
w=some value,
p= some value 
};
//// your code 

  if (w < p)
 {
   return p;
 }else if(w > p && p>0){
   //return (w , p);
 }else{
   return w;

} 返回 Obj; }

public class testhelper{
  public int p{get;set;}
  public int w{get;set;}
 }

Out是任何问题的可怕解决方案,它破坏了OOP范围的概念,如果有其他选择,应该始终避免使用。 - TravisO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接