错误:"需要对象引用才能访问非静态字段、方法或属性..."

35

我正在用C#创建一个应用程序。它的功能是评估给定的数字是否为质数,以及交换后的数字是否也是质数。

当我在Visual Studio中构建我的解决方案时,它会提示“需要一个对象引用才能访问非静态字段、方法或属性……”。我在“volteado”和“siprimo”方法上遇到了这个问题。

问题出在哪里,我该如何解决?

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Write a number: ");
            long a= Convert.ToInt64(Console.ReadLine()); // a is the number given by the user


            long av = volteado(a); // av is "a" but swapped

            if (siprimo(a) == false && siprimo(av) == false)
                Console.WriteLine("Both original and swapped numbers are prime.");
            else
                Console.WriteLine("One of the numbers isnt prime.");
            Console.ReadLine();
        }

        private bool siprimo(long a)
        {
            // Evaluate if the received number is prime
            bool sp = true;
            for (long k = 2; k <= a / 2; k++)
                if (a % k == 0) sp = false;
            return sp;
        }

        private long volteado(long a)
        {
            // Swap the received number
            long v = 0;
            while (a > 0)
            {
                v = 10 * v + a % 10;
                a /= 10;
            }
            return v;
        }
    }
}

2
欢迎来到StackOverflow!请在以后的提问中使用更具描述性的名称 :) - Matchu
请修改您的问题的格式。您代码的前几行没有被代码格式覆盖。 - Chry Cheng
3
已进行相关格式调整,标题编辑 :) - Matchu
6个回答

81

您无法从静态方法中访问非静态成员。(请注意,Main()是静态的,这是 .Net 的要求)。只需将siprimo和volteado设为静态,即在它们前面加上static关键字。例如:

 static private long volteado(long a)

@user300484,您应该点击评分下方的勾选标记此答案为正确答案。 - mxmissile
5
这个问题的真正答案是由Shazia提供的,这是一个没有编程逻辑的解决方法。 - Leandro Bardelli
当你在编写一个快速的一次性控制台程序时,这是有意义的。 - Igby Largeman
答案直接且正确,详细答案可以在此处找到[链接](https://techkluster.com/dot-net/questions/fix-object-reference-is-required-error/)。 - Ali

39
在Main方法中创建一个类,将你的所有代码放在里面,并调用该类的一个实例:
static void Main(string[] args)
{

    MyClass cls  = new MyClass();
    Console.Write("Write a number: ");
    long a= Convert.ToInt64(Console.ReadLine()); // a is the number given by the user
    long av = cls.volteado(a);
    bool isTrue = cls.siprimo(a);
    ......etc

}

7
这是解决这个问题的真正方法。 - Leandro Bardelli
是的,从长远来看并且作为良好的实践,您应该将其封装在一个类中。 - Patricio
这个解决了我的问题。 - chesco

21

在这两个方法的声明中, 只需添加static, 编译时错误就会消失!

C#中默认情况下方法是实例方法(instance methods), 它们接收一个隐式的“self”参数。通过将它们定义为静态方法,就不需要该参数(也不可用),并且该方法当然必须避免访问类的任何实例(非静态)对象或方法。

关于静态方法的更多信息
如果类和方法的访问修饰符(public vs. private)都正确,那么可以从任何地方调用静态方法,而无需先实例化类。换句话说,使用以下语法使用静态方法:

    className.classMethod(arguments)
rather than
    someInstanceVariable.classMethod(arguments)

静态方法的一个经典示例可以在System.Math类中找到,通过这些方法,我们可以调用一堆这样的方法,例如:

   Math.Sqrt(2)
   Math.Cos(Math.PI)

在没有实例化“Math”类的情况下(实际上我甚至不知道是否可能这样做)


4
感谢提供深入洞察问题的建议,而不仅仅是快速修复:这对于仍在学习基础知识的C#新手非常有用。但我有两个附带评论:1)Math是一个静态类(http://msdn.microsoft.com/en-us/library/system.math.aspx),所以您的怀疑是正确的:它无法实例化;2)也许您应该提供一些实例方法的示例...它们普遍存在的ToString()方法就是一个例子。 - Edurne Pascual

3

将您的签名更改为private static bool siprimo(long a)和private static long volteado(long a),看看会得到什么结果。


0

你只需要将siprimo和volteado方法设为静态的。

private static bool siprimo(long a)

并且

private static long volteado(long a)

0
错误信息表示您需要在 Program 类的实例上调用 volteadosiprimo 方法。例如:
...
Program p = new Program();
long av = p.volteado(a); // av is "a" but swapped

if (p.siprimo(a) == false && p.siprimo(av) == false)
...

它们不能直接从Main方法中调用,因为Main是静态的,而volteadosiprimo不是。

最简单的解决方法是将volteadosiprimo方法设为静态:

private static bool siprimo(long a)
{
    ...
}

private static bool volteado(long a)
{
   ...
}

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