【问题标题】:Abstract class as ref parameter - compiler error抽象类作为 ref 参数 - 编译器错误
【发布时间】:2011-03-30 22:56:39
【问题描述】:

我在 VS2010 上有这个简单的示例:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            AbsClass absClass = new ConClass();
            // I have tried this also and the error is different:
            // ConClass absClass = new ConClass();
            absClass.Id = "first";
            Console.WriteLine(absClass.Id);
            MyMethod(ref absClass);  // <<- ERROR.
            Console.WriteLine(absClass.Id);
            Console.ReadKey();
        }

        public void MyMethod(ref AbsClass a)
        {
            a.Id = "new";
        }
    }

    public abstract class AbsClass
    {
        public string Id { get; set; }
    }

    public class ConClass : AbsClass { }
}

我想知道为什么这不能正确构建。

【问题讨论】:

  • 你得到的编译器错误是什么?
  • “非静态字段、方法或属性 'ConsoleApplication1.Program.MyMethod(ref ConsoleApplication1.AbsClass)' 需要对象引用” - 有点说明问题,不是吗?
  • @Femaref 的回答是正确的。注释掉的版本(带有 ConClass)不起作用的原因是作为参数传递给 ref 参数的变量类型必须与参数的类型完全匹配。这可以确保方法中的任何分配都可以正常工作。

标签: c# abstract-class ref


【解决方案1】:

您需要将您的MyMethod 设为静态:

    public static void MyMethod(ref AbsClass a)
    {
        a.Id = "new";
    }

问题不在于抽象类,“问题”在于静态Main 方法。静态方法没有实例,因此不能调用实例方法。

msdn on static classes and static members.

【讨论】:

  • 是的,没错。它现在作为静态运行。但为什么 ?或者,请提供一些官方文档链接来阅读它?
  • 对不起...我没有在代码下方看到您的评论。你的意思是如果我把它放在一个非 Main 静态方法上,原始代码会运行良好吗?
  • 我添加了一个链接,但简单来说,原因已经在帖子中。 Main 方法是static,因此,与Program 类的特定实例无关。因此,它也只能调用不依赖于Program 实例的其他方法。
  • 不,它没有 - Main 方法是您的应用程序的入口点,运行时在您的代码中查找静态 Main 方法。如果它没有找到,你会得到一个异常并且程序不会运行。
  • 我想明白了。对于未来的读者,我将在没有静态子句的 MyMethod (在管理器类中)运行良好的问题中放置一个代码。谢谢 Femaref。
【解决方案2】:

您要么需要将 MyMethod 方法设为静态:

public static MyMethod(ref AbsClass a)
{
    a.Id = "new";
}

或者最好创建Program 类的实例,并从该实例调用MyMethod

Program p = new Program();
p.MyMethod(ref abs);

第一种方法起作用的原因是Main 方法被标记为静态,并且不绑定到Program 类的实例。 .NET Framework CLR 在您的程序集中搜索名为Main 的静态方法,该方法采用String 的数组,并将该函数作为入口点。您会注意到很多教程甚至 MSDN 代码示例都使用 static 关键字标记 Program 类,当一个类中的所有方法都只包含静态方法时,这被认为是最佳实践。

第二种方法有效的原因,以及为什么首选这种方法,是因为您将MyMethod 定义为一个实例方法。基本上,您需要一个对象的实例才能执行实例方法; new 关键字创建指定类型的实例。静态方法可以在没有对象实例的情况下调用,但也不能访问任何非静态实例成员(属性、私有/公共变量等)。通常,您希望避免使用静态方法和类,除非您必须实现实用程序类、利用扩展方法或提供辅助方法。

【讨论】:

    猜你喜欢
    • 2016-11-18
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 2012-09-18
    • 2020-05-13
    相关资源
    最近更新 更多