抽象类作为ref参数 - 编译器错误

时间:2011-03-30 22:56:39

标签: c# abstract-class ref

我在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 { }
}

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

2 个答案:

答案 0 :(得分:4)

您需要使MyMethod静态:

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

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

msdn on static classes and static members

答案 1 :(得分:0)

您需要将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关键字创建指定类型的实例。静态方法可以在没有对象实例的情况下调用,但也不能访问任何非静态实例成员(属性,私有/公共变量等)。通常,除非必须实现实用程序类,使用扩展方法或提供帮助程序方法,否则您希望避免使用静态方法和类。