Абстрактный класс как параметр ref - ошибка компилятора - PullRequest
0 голосов
/ 31 марта 2011

У меня есть простой пример 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 ]

4 голосов
/ 31 марта 2011

Вам нужно сделать MyMethod статичным:

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

Проблема не в абстрактном классе, а "проблема" - в статическом методе Main. Статические методы не имеют экземпляра и поэтому не могут вызывать методы экземпляра.

msdn для статических классов и статических членов .

0 голосов
/ 31 марта 2011

Вам либо нужно сделать статический метод 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 помечают класс Program ключевым словом static, что считается наилучшей практикой, когда все методы в классе содержат только статические методы.

Причина, по которой работает второй метод и почему он предпочтителен, заключается в том, что вы определили MyMethod как метод экземпляра . По сути, вам нужен экземпляр объекта, чтобы выполнить метод экземпляра; Ключевое слово new создает экземпляр указанного типа. Статические методы можно вызывать без экземпляра объекта, но они также не могут получить доступ к каким-либо нестатическим элементам экземпляра (свойствам, частным / общедоступным переменным и т. Д.). Как правило, вы хотите избегать статических методов и классов, если вы не должны реализовывать служебный класс, использовать методы расширения или предоставлять вспомогательные методы.

...