“无法通过实例引用访问成员,请改为使用类型名称来限定它”,而我确实使用类型名称

时间:2018-09-04 09:57:25

标签: c# static singleton

我有一个这样的示例代码:

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对象,然后info要求是非静态的才能能够在实例而不是类型上工作?

4 个答案:

答案 0 :(得分:4)

在C#中,实例方法只能在实例上调用,而静态方法只能在类/结构本身上调用。

为什么不能将Info链接到SimpleLogger.Instance()上?

因为SimpleLogger.Instance(...)返回了SimpleLogger instance ,并且您试图对返回的值调用静态方法。返回的值是SimpleLogger的实例,因此您不能在其上调用静态方法。

通过将Info设为非静态,可以在实例上调用它。因此,可以在Instance()的返回值上调用它。

造成混淆的一个原因可能是您在方法链中看不到SimpleLogger的实例,因此为了更好地说明链接方法的思想,这是

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

等效于:

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

现在查看SimpleLogger的实例吗?

答案 1 :(得分:3)

与您所写的完全相同。您在类上调用静态方法,而不能在对象上调用它们,并且您的Instance方法返回SimpleLogger类的具体对象。如果要链接方法(即SimpleLogger.Instance("path").Info("info");),则必须将Info(string info)更改为非静态类。使这些方法为非静态方法并使类为Singleton

更有意义

答案 2 :(得分:2)

致电时

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");

答案 3 :(得分:0)

您正在从实例中调用静态方法。如我所见,也许您正在尝试将Logger类创建为单例模式。然后,您只需将Info(string 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}");
            }
        }
    }