将对象传递给方法会导致对象没有值?

时间:2014-07-12 01:34:40

标签: c# object methods mono monodevelop

我是C#的新手,当我尝试将一个对象从一个方法传递到另一个方法时,我遇到了一个奇怪的问题。我的问题是,当我从第二个方法中的对象调用一个值时,它什么都不返回。

如果以前有人询问过这样的话,请原谅我。我所有的努力都发现了数百个关于正常操作和传递对象引用之间差异的重复问题,而不是简单地传递对象。 (我尝试了两种方式,似乎都没有用。)

简单地说,我无法找到解释为什么我的对象的值在传递给另一个方法时为空的原因。

我已经详细介绍了我的课程的定义以及他们的方法的作用。我还介绍了如何在我的项目中实现此问题。最后,我发布了输出,以便您可以看到我正在谈论的内容(因为我不太了解这个问题,并且最好先向您展示症状 - 手)。

如何正确地将对象传递给另一个函数? (即:我做错了什么?)

类定义:

// 'class Expression' stores an expression in postfix notation
// and does all kinds of sweet math stuffs to it:
public class Expresssion
{
    public List<string> Value;

    public Expression (List<string> postfix_input)
    {
        Value = postfix_input;
    }
    //(...)
}

// 'class Terp' is a static class designed to convert user-readable
// infix expressions into tokenized lists in postfix notation so I
// can more easily do math.
public static class Terp
{
    public static List<string> ToPostfix (string infix_input)
    {
        //{"1+2"} >> {"1","2","+"}
        return postfix_output;
    }
    public static string ToInfix (List<string> postfix_input)
    {
        //{"1","2","+"} >> {"1+2"}
        return infix_output;
    }
    public static string CompileString (List<string> tokens_input)
    {
        //{"1","2","+"} >> {"12+"}
        return string_output;
    }
    //(...)
}

实现:

public static void StepOne (string command, string user_input)
{
    // NOTE: 'command' and 'user_input' are both provided by parsing the
    // user's input via a graphical interface (I'm simplifying here because
    // I don't want this to get cluttered with regex stuff).

    // Creating the Expression instance:
    Expression target_expr = new Expression(Terp.ToPostfix(user_input));

    // Setting up console messages to make sure the input is there:
    Console.WriteLine("Command: '" + command + "'");
    Console.WriteLine("Expression: '" + Terp.CompileString(target_expr.Value) + "'");

    // Passing 'Expression' object into 'StepTwo()':
    StepTwo(command, target_expr);
}


static void StepTwo (string command, Expression target_expr)
{
    // Making sure everything made it through the Stargate alright:
    Console.WriteLine("------------------------------");
    Console.WriteLine("Command: '" + command + "'");
    Console.WriteLine("Expression: '" + Terp.CompileString(target_expr.Value) + "'");
}

输出:

Command: 'dd'
Expression: '12+'
------------------------------
Command: 'dd'
Expression: ''

作为最后一点,&#39; Terp&#39;上课检查。 “表达”也是如此。类。在所有其他情况下,两者都表现出色。将我的对象传递给StepTwo()后,如果我尝试调用target_expr.Value[0],我的程序会抛出一个超出范围的&#34;参数。异常。

同样,如果有人能解释这里的错误,我真的很感激。我对C#非常陌生,把这一个弄清楚让我非常难过。

提前致谢!

更新

很抱歉找不到方法。这是CompileString()的代码:

public static string CompileString (List<string> tokens_input)
    {
        string str = string.Empty;
        foreach (string token in tokens_input)
        {
            str = str + token;
        }
    return str;
    }

我不知道这会如何改变target_expr的价值,但我显然遗漏了一些东西。

2 个答案:

答案 0 :(得分:1)

我已经编译了你的代码,它完美无缺。我把断点和每一步都检查了所有的值,每件事情都很好。

这是代码。尝试执行它:

您的代码:

// 'class Expression' stores an expression in postfix notation
// and does all kinds of sweet math stuffs to it:
public class Expression
{
    public List<string> Value;

    public Expression(List<string> postfix_input)
    {
        Value = postfix_input;
    }
}

// 'class Terp' is a static class designed to convert user-readable
// infix expressions into tokenized lists in postfix notation so I
// can more easily do math.
public static class Terp
{
    public static List<string> ToPostfix(string infix_input)
    {
        List<string> postfix_output = new List<string>();
        foreach (char c in infix_input)
        {
            postfix_output.Add(c.ToString());
        }
        //{"1+2"} >> {"1","2","+"}
        return postfix_output;
    }
    public static string ToInfix(List<string> postfix_input)
    {
        string infix_output = String.Empty;
        //{"1","2","+"} >> {"1+2"}
        return infix_output;
    }
    public static string CompileString(List<string> tokens_input)
    {
        string str = string.Empty;
        foreach (string token in tokens_input)
        {
            str = str + token;
        }
        //{"1","2","+"} >> {"1,2,+"}
        return str;
    }
}

<强>实施

static void Main(string[] args)
{
    StepOne("dd", "12+");
    Console.ReadLine();
}

public static void StepOne(string command, string user_input)
{
    // NOTE: 'command' and 'user_input' are both provided by parsing the
    // user's input via a graphical interface (I'm simplifying here because
    // I don't want this to get cluttered with regex stuff).

    // Creating the Expression instance:
    Expression target_expr = new Expression(Terp.ToPostfix(user_input));

    // Setting up console messages to make sure the input is there:
    Console.WriteLine("Command: '" + command + "'");
    Console.WriteLine("Expression: '" + Terp.CompileString(target_expr.Value) + "'");

    // Passing 'Expression' object into 'StepTwo()':
    StepTwo(command, target_expr);
}

static void StepTwo(string command, Expression target_expr)
{
    // Making sure everything made it through the Stargate alright:
    Console.WriteLine("------------------------------");
    Console.WriteLine("Command: '" + command + "'");
    Console.WriteLine("Expression: '" + Terp.CompileString(target_expr.Value) + "'");
}

<强>输出:

Command: 'dd'
Expression: '12+'
------------------------------
Command: 'dd'
Expression: '12+'

<强>调试:

在第1步:

进入方法target_expr之前Step 2的值。

enter image description here

在第2步:

方法target_exprStep 2的值。

enter image description here

参考没问题。现在尝试匹配代码,可能是你遗漏了一些东西。

答案 1 :(得分:0)

我完全解决了我的问题...

我完全误解了如何在C#中处理对象。我也没有意识到(虽然现在对我很明显)在C#中List<>对象而不是简单的数据类型(就像使用python一样)。

答案(一如既往)可以在文档和关于最佳实践的好文章中找到(一旦我知道要寻找什么):

问题出在我的方法ToInfix()ToPostfix()中。 (实际上,问题出在{em>处理转换的Terp类中的每个方法。)

简而言之,我没有意识到target_expr.Value是对列表对象的引用。我也没有意识到,当我将该对象传递给方法时,它会传递对象的引用(而不是其值的副本),并且任何更改都会影响原始对象。

长话短说,Terp中的一种方法在postfix_input列表从一种形式转换为下一种形式时会吃掉它们。这出现了target_expr.Value

解决方案很简单。将List<>对象传递给ToInfix()时,我会将令牌换成令牌副本,然后再将其传递给Terp中的任何私有方法:

public static string ToInfix (List<string> postfix_input)
{
    // Make a one-to-one copy of a list:
    List<string> postfix_copy = new List<string>();
    foreach (string token in postfix_input)
    {
        postfix_copy.Add(token);
    }
    // Then do stuff...
    //(...)
}

此修复程序使一切都按预期运行。

现在我知道这是对象的工作方式,我将通过并清理Terp以确保正确处理。特别感谢@Shaharyar,因为看着他的例子让我走上了正轨,而@AlexD让我找到了正确的位置。

谢谢大家的时间!