【问题标题】:Trying to return multiple values by passing single value in function in c#尝试通过在c#中的函数中传递单个值来返回多个值
【发布时间】:2019-06-21 21:24:31
【问题描述】:

我正在尝试从传递参数并将其存储在变量ZDO_S的函数中返回多个值

在变量 ZDO_S 中,我试图存储两个值,我将通过传递单个值 'row["TVM_LS_NO"].ToString()' 来获得,这是在 'getdo' 函数中从数据库获取的

var ZDO_S = getDo(row["TVM_LS_NO"].ToString());

方法如下:

private static (string TVD_LS_NO, string TVD_INV_NO) getDo(string DoNo)
{           
    try
    {
        using (OracleConnection con = new OracleConnection(ConfigurationManager.ConnectionStrings["Oracle_To_Sql.Properties.Settings.Setting"].ToString()))
        {
            string query = "select SUBSTR(TVD_DO_ITEM_NO,'1','10') from T_VEHICLE_DTL1  where TVD_LS_NO=:TVD_LS_NO";
            OracleCommand myCommand = new OracleCommand(query, con);
            DataTable dt = new DataTable();
            OracleDataAdapter da = new OracleDataAdapter(myCommand);
            da.SelectCommand = new OracleCommand(query, con);                    
            da.Fill(dt);                    

            foreach (DataRow row in dt.Rows)
            {
                string TVD_LS_NO = row["TVD_LS_NO"].ToString();
                string TVD_INV_NO = row["TVD_INV_NO"].ToString();                        
            }

            return (TVD_LS_NO, TVD_INV_NO);
        }
    }
    catch (Exception ex)
    {
        throw;
    }

}

应返回预期值并将其存储在 ZDO_S 变量中。

  1. 实际出现错误“无法将 void 分配给隐式类型变量”在

    var ZDO_S=getDo(row["TVM_LS_NO"].ToString());
    
  2. IDentifier 预计在

    private static (string TVD_LS_NO, string TVD_INV_NO) getDo(string DoNo)
    
  3. 因为 'Program.getDo(String) 返回 void ,所以返回关键字后面必须跟一个对象表达式

    return (TVD_LS_NO, TVD_INV_NO);
    

【问题讨论】:

  • 方法签名的语法看起来是正确的,您确定您使用的是 C#7 或更高版本吗?
  • 您的变量 TVD_LS_NOTVD_INV_NOforeach 块中定义,因此在您执行 return 时不可见。
  • 顺便说一句,我强烈建议您开始遵循 .NET 命名约定,并避免您在此处获得的冗余 try/catch-then-throw 块。
  • 如果不是 C#7,则不能使用此语法。像这样的元组是在 C#7 中添加的,因此您必须回退到 old tupels。它们的定义是这样的Tupel<string, string>。它们的缺点是只有名为“Item1”和“Item2”的属性而不是您想要的名称,但以相同的方式工作。
  • 我认为,如果任何方法需要返回多个值,为它定义一个类/结构会使代码更具可读性(除了 tryParseout 关键字这样的情况,这不是很对我也很有吸引力)。

标签: c#


【解决方案1】:

我对 C# 不是很熟悉,但是如果您想在单个 return 语句中返回多个值,唯一的方法通常是数组或对象。在您的情况下,数组将是最简单的。

  • 返回类型定义看起来不像是数组返回类型,试试

private static string[] getDo() {...

  • return 语句本身看起来不像数组,请尝试将值作为数组返回

  • 您在 foreach 循环内定义变量,这通常会使它们在循环外无法访问。尝试在循环外定义变量并在循环中使用它们。

我不知道这是否是有效的 C#,但类似这样:

private static String[] getDo(string DoNo)
    {           
        try
        {
            using (OracleConnection con = new OracleConnection(ConfigurationManager.ConnectionStrings["Oracle_To_Sql.Properties.Settings.Setting"].ToString()))
            {
                String[] toReturn = new String[2];
                string TVD_LS_NO, TVD_INV_NO;
                string query = "select SUBSTR(TVD_DO_ITEM_NO,'1','10') from T_VEHICLE_DTL1  where TVD_LS_NO=:TVD_LS_NO";
                OracleCommand myCommand = new OracleCommand(query, con);
                DataTable dt = new DataTable();
                OracleDataAdapter da = new OracleDataAdapter(myCommand);
                da.SelectCommand = new OracleCommand(query, con);                    
                da.Fill(dt);                    
                foreach (DataRow row in dt.Rows)
                {
                    TVD_LS_NO = row["TVD_LS_NO"].ToString();
                    TVD_INV_NO = row["TVD_INV_NO"].ToString();                        
                }
                toReturn[0] = TVD_LS_NO;
                toReturn[1] = TVD_INV_NO;
                return toReturn;
            }
        }
        catch (Exception ex)
        {

            throw;
        }

    }

不确定这是否是最佳答案,但我希望它能将您推向正确的方向。

【讨论】:

  • 这是一个想法,但它并没有使用元组,它带来了一些不错的特性,就像你确切地知道值在哪里,你可以命名它们,你可以有不同的类型,等等。跨度>
  • 那么这种方式在他的用例中可能不是最好的(但如果你不需要这些功能,我猜它是原始和简单的)。
【解决方案2】:

这里有几个问题,让我们尝试一一解决。

  • 首先,您说要返回两个值,但您在 for 循环中分配它们,这可能意味着它们将被分配多次。这是故意的吗?还是您希望 for 循环只运行一次?

  • 然后,您在 for 循环中声明变量,这意味着当您退出循环时它们将被销毁,失去它们的值并使编译器生气(和悲伤)。

  • 您正在尝试使用自 C# 7 以来编译器已知的返回结果语法。如果您使用的是以前的版本,它将根本不起作用。

  • 最后,如果你不在 catch 块中做某事,你的 try/catch 就完全没用了,所以你可以删除它。

如果我可以建议some additional understanding on TUples

所以,如果我们在 C# 7 中重新开始,它看起来像这样:

private static (string TVD_LS_NO, string TVD_INV_NO) getDo(string DoNo)
{
    //We declare our return value(s)
    var toReturn(TVD_LS_NO: "", TVD_INV_NO: "");

    using (OracleConnection con = new OracleConnection(ConfigurationManager.ConnectionStrings["Oracle_To_Sql.Properties.Settings.Setting"].ToString()))
    {
        string query = "select SUBSTR(TVD_DO_ITEM_NO,'1','10') from T_VEHICLE_DTL1  where TVD_LS_NO=:TVD_LS_NO";
        OracleCommand myCommand = new OracleCommand(query, con);
        DataTable dt = new DataTable();
        OracleDataAdapter da = new OracleDataAdapter(myCommand);
        da.SelectCommand = new OracleCommand(query, con);                    
        da.Fill(dt);                    

        foreach (DataRow row in dt.Rows)
        {
            //We assign our return values
            toReturn.TVD_LS_NO = row["TVD_LS_NO"].ToString();
            toReturn.TVD_INV_NO = row["TVD_INV_NO"].ToString();                        
        }

        return toReturn;
}

但这仅适用于 C# 7

如果你不使用 C# 7,你还有其他可能:

  1. Use ref keyword

    int value = 0;
    MyFunction(ref value);
    Console.WriteLine(value); //Outputs 10
    
    void MyFunction(ref int value)
    {
        value = 10;
    }
    
  2. Use out keyword

    int value;
    MyFunction(value);
    Console.WriteLine(value); //Outputs 10
    
    void MyFunction(out int value)
    {
        value = 10;
    }
    

    要了解两者之间的差异,additional reading. 您可以根据需要使用任意数量的 ref/out 参数。

  3. 使用小类/结构(首选方式)

    public struct MyResultValues //could be public class MyResultValues
    {
        public int result1;
        public string result2;
    }
    
    MyResultValues result = MyFunction();
    Console.WriteLine(result.result1);
    Console.WriteLine(result.result2);
    
    public MyResultValues MyFunction()
    {
        MyResultValues toReturn = new MyResultValues();
        toReturn.result1 = 10;
        toReturn.result2 = "Hello World !";
        return toReturn;
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    相关资源
    最近更新 更多