“无法使用实例引用访问成员,而是使用类型名称来限定它”,并且我使用类型名称

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“无法使用实例引用访问成员,而是使用类型名称来限定它”,并且我使用类型名称相关的知识,希望对你有一定的参考价值。

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

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需要非静态才能处理实例而不是类型?

答案

在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的实例?

另一答案

就像你写的那样。你在类上调用静态方法,不能在对象上调用它们,而你的Instance方法返回SimpleLoggerclass的具体对象。如果你想要链接方法(即SimpleLogger.Instance("path").Info("info");),你必须将Info(string info)更改为非静态类。让这些方法是非静态的更有意义,并使类成为Singleton

另一答案

当你打电话的时候

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

.Instance(...)返回一个SimpleLogger类的实例。直接在该实例上调用.Info会导致此警告,因为.Info(...)被定义为static。

你可以像这样重写.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");
另一答案

您正在从其实例调用静态方法。正如我所看到的,也许您正在尝试将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}");
            }
        }
    }

以上是关于“无法使用实例引用访问成员,而是使用类型名称来限定它”,并且我使用类型名称的主要内容,如果未能解决你的问题,请参考以下文章