我有一个这样的示例代码:
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要求是非静态的才能能够在实例而不是类型上工作?
答案 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}");
}
}
}