«Член не может быть доступен с помощью ссылки на экземпляр, вместо этого укажите его имя типа», и я действительно использую имя типа - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть пример кода, подобный этому:

public class SimpleLogger
{
    private static SimpleLogger logger;
    private string path = null;

    protected SimpleLogger(string path)
    {
        this.path = path;
    }

    public static SimpleLogger Instance(string path)
    {
        if (logger == null)
        {
            logger = new SimpleLogger(path);
        }
        return logger;
    }

    public static void Info(string info)
    {
        string path = $"{logger.path}{DateTime.Now.ToShortDateString()}_Info.txt";
        using (StreamWriter writer = new StreamWriter(path))
        {
            writer.WriteLine($"{DateTime.Now} - {info}");
        }
    }
}

и когда я звоню:

SimpleLogger.Instance("path").Info("info");

Ошибка:
к члену нельзя получить доступ с помощью ссылки на экземпляр, квалифицируйте его как имя типа вместо статического метода

Но я действительно использую имя типа, не так ли?

Но когда я называю это так:

SimpleLogger.Instance("path");
SimpleLogger.Info("info");  

это на самом деле работает нормально.

Чтобы он работал встроенным, я должен сделать метод Info нестатичным, а затем встроенный вызов также работает нормально. Это почему? Я не понимаю механизм здесь. Может кто-нибудь объяснить? Это потому, что метод Instance возвращает объект SimpleLogger, а затем информация должна быть нестатической, чтобы иметь возможность работать с экземпляром, а не над типом?

Ответы [ 4 ]

0 голосов
/ 04 сентября 2018

Вы вызываете статический метод из его экземпляра. Как я вижу, возможно, вы пытаетесь создать класс Logger как одноэлементные шаблоны. Затем вы просто делаете метод Info (строковая информация) для нестатического метода:

    public class SimpleLogger
    {
        private static SimpleLogger logger;
        private string path = null;

        protected SimpleLogger(string path)
        {
            this.path = path;
        }

        public static SimpleLogger Instance(string path)
        {
            if (logger == null)
            {
                logger = new SimpleLogger(path);
            }

            return logger;
        }

        public void Info(string info)
        {
            string path = $"{logger.path}{DateTime.Now.ToShortDateString()}_Info.txt";

            using (StreamWriter writer = new StreamWriter(path))
            {
                writer.WriteLine($"{DateTime.Now} - {info}");
            }
        }
    }
0 голосов
/ 04 сентября 2018

Когда вы звоните

SimpleLogger.Instance("path").Info("info");

.Instance (...) возвращает экземпляр класса SimpleLogger. Вызов .Info непосредственно для этого экземпляра вызывает это предупреждение, потому что .Info (...) определяется как статический.

Вы можете переписать .Info () так:

public void Info(string info)
{
    string path = $"{this.path}{DateTime.Now.ToShortDateString()}_Info.txt";
    using (StreamWriter writer = new StreamWriter(path))
    {
        writer.WriteLine($"{DateTime.Now} - {info}");
    }
}

Таким образом, вы можете позвонить

SimpleLogger.Instance("path").Info("info");

без предупреждения, но вы больше не можете это называть:

SimpleLogger.Info("info");
0 голосов
/ 04 сентября 2018

В C # методы экземпляра могут быть вызваны только для экземпляра, тогда как статические методы могут быть вызваны только для самого класса / структуры.

Почему вы не можете связать Info на SimpleLogger.Instance()?

Поскольку SimpleLogger.Instance(...) возвращает экземпляр из SimpleLogger, и вы пытаетесь вызвать статический метод для возвращаемого значения. Возвращаемое значение является экземпляром SimpleLogger, поэтому вы не можете вызывать статический метод для него.

Делая Info нестатичным, вы активируете его для экземпляра. Следовательно, вы можете вызвать его по возвращаемому значению Instance().

Одной из причин вашего замешательства может быть то, что вы не видите экземпляр SimpleLogger в своей цепочке методов, поэтому, чтобы лучше проиллюстрировать идею методов цепочки, это:

SimpleLogger.Instance("path").Info("info");

эквивалентно:

SimpleLogger logger = impleLogger.Instance("path");
logger.Info("info");

См. Экземпляр SimpleLogger сейчас?

0 голосов
/ 04 сентября 2018

Точно так же, как вы написали. Вы вызываете статические методы для класса, не можете вызывать их для объектов, и ваш метод Instance возвращает конкретный объект класса SimpleLogger. Если вы хотите связать методы (т.е. SimpleLogger.Instance("path").Info("info");), вам придется изменить Info(string info) на нестатический класс. Более логично, чтобы эти методы были нестатичными, а класс был Singleton

...