2011-03-30 65 views
0

我有VS2010这个简单的例子:抽象类作为ref参数 - 编译器错误

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

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

+0

你得到的编译器错误是什么? – 2011-03-30 22:58:12

+0

“非静态字段,方法或属性需要对象引用'ConsoleApplication1.Program.MyMethod(ref ConsoleApplication1.AbsClass)'” - 有点儿说这一切,不是吗? – 2011-03-30 23:02:36

+0

@ Femaref的回答是正确的。注释版本(使用ConClass)不起作用的原因是,作为参数传递给ref参数的变量类型必须完全匹配参数的类型。这可以确保方法中的任何分配都能正常工作。 – 2011-03-30 23:08:08

回答

4

你需要让你的MyMethod静:

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

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

msdn on static classes and static members

+0

是的,没错。它现在以静态方式运行。但为什么 ?或者,请联系官方文档阅读有关它? – ferpega 2011-03-30 23:03:58

+0

对不起......我在代码下面没有看到您的评论。你的意思是如果我把它放在一个非主静态方法原始代码将运行良好? – ferpega 2011-03-30 23:06:36

+0

我添加了一个链接,但简而言之,原因已在帖子中。 'Main'方法是'static',因此不与'Program'类的特定实例关联。因此,它只能调用其他不依赖于'Program'实例的方法。 – Femaref 2011-03-30 23:07:10

0

要么你需要让你的MyMethod方法静:

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

或者preferrably,创建Program类的一个实例,并从该实例调用MyMethod

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

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

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

相关问题