C#: 要使用非静态字段、方法或属性,需要对象引用

3

很遗憾,在有如此多相关问题时我还要问这个问题,但是我无法找到/理解我正在寻找的答案。

// 2. 开发一个程序将货币X转换为货币Y,反之亦然。

using System;

class Problem2
{
    static void Main (string[] args)
    {
        while (true) {
            Console.WriteLine ("1. Currency Conversion from CAD to Won");
            Console.WriteLine ("2. Currency Conversion from Won to Cad");
            Console.Write ("Choose from the Following: (1 or 2)? ");
            int option = int.Parse( Console.ReadLine() );
            //double x;
            if (option == 1) {
                Console.WriteLine ("Type in the amount you would like to Convert CAD to Won: ");
                //double y =double.Parse( Console.ReadLine());
                //Console.WriteLine( cadToWon( y ) );
                Console.WriteLine( cadToWon( double.Parse( Console.ReadLine() ) ));
            }
            if (option == 2) {
                Console.WriteLine ("Type in the amount you would like to Convert Won to CAD: ");
                Console.WriteLine( wonToCad (double.Parse( Console.ReadLine())));
            }
        }
    }

    double cadToWon( double x )
    {
        return x * 1113.26;
    }

    double wonToCad( double x)
    {
        return x / 1113.26;
    }
}

这让我收到了错误信息:“需要对象引用才能访问非静态字段、方法或属性'Problem2...'”。我知道如果在这些方法前面添加static,我就能运行程序,但我想知道为什么需要这样做(我认为是因为Main是静态的?)以及我需要改变什么才能在不添加static的情况下使用这些方法?
谢谢。

有点有趣,所有人都没有回答问题,而是直接说“让它们静态”,但问题是为什么要这样做,以及如何在不使用静态的情况下实现? - LightStriker
是的,哈哈,但人们听到了你的话并包含了解释。谢谢! - Charles Han
5个回答

4

如果您想从Main方法调用cadToWon和wonToCad,由于Main方法是静态的,所以cadToWon和wonToCad也必须是静态的。

static double cadToWon(double x) //...


static double wonToCad(double x) //...

另一个选择是将您的Main、cadToWon和wonToCad方法的所有逻辑分解到一个新的类中,然后让您的Main方法简单地设置和运行该新类。但我怀疑这可能超出了您的任务范围。
回答您关于为什么添加static使其起作用的问题:
静态方法在类的所有实例之间共享。因此,无论您在类Problem2的哪个实例中,只有一个Main方法在所有实例之间共享。
然而,cadToWon是一个实例方法。它属于类Problem2的特定实例。
因此,您不能从Main调用cadToWon,因为Main不知道要调用cadToWon的Problem2实例。Main不知道要调用cadToWon的实例,因为Main不属于任何实例。

它们不一定要是静态的,也不一定要在另一个类中。我承认这是更好的设计,但这并不是一个限制。 - LightStriker
@Marc - 当然你是对的。他可以创建类Problems2的一个新实例,并从Main中调用该实例上的cadToWon。我只是想让事情对OP保持简单。 - Adam Rackis
他知道将它们设为静态可以解决问题... 他的问题是为什么以及如何在不使用静态的情况下使其正常工作?有点奇怪,每个人都回答“将它们设为静态”。 - LightStriker
@Marc - 确实。谢谢你指出来。我为他添加了一个解释。 - Adam Rackis
谢谢Adam和Marc-André两位。 - Charles Han

0

这个解决方案正是在这里寻找的。 试图将一个对象从静态Main方法传递到Program类中的方法几乎是不可能的,除非:

 `Program ProgramInstance = new Program();
 ProgramInstance.ProcessObject(MyObject);`

0
将您的方法设置为static即可解决该问题。您无法从静态方法(例如static void main(..))调用实例成员(未带有static)。它们两者必须都声明为static,或者您可以在其中包含方法的类中创建实例,并通过实例访问它们。我认为您在这里不需要那个。
static double cadToWon( double x )
{
    return x * 1113.26;
}

static double wonToCad( double x)
{
    return x / 1113.26;
}

通过实例访问

Program2 p2 = new Program2();
double x = p2.wonToCad(10);

我知道如果在方法前面加上static,我就能运行程序,但我想知道为什么需要它。 - LightStriker
你需要它是因为main是静态的。我的答案包括如何添加static并仍然调用方法 - 创建Program2的实例。 - codingbiz

0

这是因为Main是静态的,没有被分配给Problem2的任何实例。不知道要将变量发送到Problem2的哪个实例,它无法调用正确的方法。

现在,您的方法不会修改任何Problem2的字段。但是它们可能会,这就是整个问题所在。它们应该修改哪个Problem2的实例?静态方法无法知道。

因此,如果您初始化了Problem2的一个实例,您可以从静态的Main中调用它自己版本的方法。

Problem2 problem = new Problem2();

problem.cadToWon(...)

-1

如果您不想将它们更改为静态的,那么只需将它们移动到另一个类中,然后在 Main 中创建一个对象并使用这些函数。


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