C#:为什么';这项静态作业不管用吗?
我得到错误“name\u client在当前上下文中不存在。”与“database”变量相同C#:为什么';这项静态作业不管用吗?,c#,C#,我得到错误“name\u client在当前上下文中不存在。”与“database”变量相同 namespace MongoDB_Test { class Program { protected static IMongoClient _client; protected static IMongoDatabase _database; _client = new MongoClient(); // error here
namespace MongoDB_Test
{
class Program
{
protected static IMongoClient _client;
protected static IMongoDatabase _database;
_client = new MongoClient(); // error here
_database = _client.GetDatabase("test"); // same error but for _database variable
}
}
以下代码没有错误:
namespace MongoDB_Test
{
class Program
{
protected static IMongoClient _client = new MongoClient();
protected static IMongoDatabase _database = _client.GetDatabase("test");
}
}
为什么第一个代码块会出现错误?移动此项:
_client = new MongoClient();
_database = _client.GetDatabase("test");
对于一个方法,在本例中是static Main()
这里没有错误:
protected static IMongoClient _client = new MongoClient();
因为new MongoClient()
不会被执行,而是隐式地被复制到静态构造函数中,该构造函数是一个方法,它在方法中执行
底线是,只能在方法中执行代码。除非是基本声明/初始化行,否则不能在方法之外编写代码。命令式代码语句在方法范围之外没有真正意义。这就是为什么你的第二个例子有效 但是,您可以编写静态构造函数:
class Program
{
protected static IMongoClient _client;
protected static IMongoDatabase _database;
static Program()
{
_client = new MongoClient();
_database = _client.GetDatabase("test");
}
}
请记住,字段初始值设定项(静态或实例)和构造函数(静态或实例)以及方法在对象构造过程中都是在非常不同的时间执行的。如果代码依赖于计时,则需要确保在需要时进行初始化。您缺少静态构造函数。试试这个:
namespace MongoDB_Test
{
class Program
{
protected static IMongoClient _client;
protected static IMongoDatabase _database;
static Program()
{
_client = new MongoClient();
_database = _client.GetDatabase("test");
}
}
}
基本上:
protected static IMongoClient _client = new MongoClient();
protected static IMongoDatabase _database = _client.GetDatabase("test");
可被视为这一功能的等效物:
static Program()
{
_client = new MongoClient();
_database = _client.GetDatabase("test");
}
也就是说,字段初始化和构造函数不会同时执行-会发生一系列事件,如果您对MSDN站点感兴趣,可以查看这些事件。您是否正在尝试编写静态构造函数?这只是因为第一个块不是正确的方法,而第二个块是正确的。我怀疑如果有足够的调用,C#编译器人员可以让第一个工作,但这是相当难看的代码(第二个也不是完美的);前者声明没有初始值的静态成员,然后使用一些普通赋值语句尝试为这些成员赋值。您不能在那里有赋值语句。@BoltClock否。我只是想熟悉一些提供的代码。提供了第二段代码,我想知道为什么不能用第一种方法编写。@EugeneFedotov这是一个语法问题。该语言允许您在同一位置(使用“字段”时)声明和初始化,但不允许先声明然后在其他位置初始化。类块不是一个算法结构。
因为它不会被执行,而是隐式地被复制到静态构造函数中,该构造函数是一个方法,它在方法内部执行。字段初始化在不同的时间点发生。互联网上有很多文章对此进行了解释,包括MSDN。这里有一个链接可以帮助您:。您应该查找的引号是:类的静态字段变量初始值设定项对应于按文本顺序执行的赋值序列,它们在类声明中出现。如果类中存在静态构造函数(第10.11节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。
@code4life,这意味着它们会被复制到静态构造函数的开头。Eric Lippert(是的,以前是Microsoft的C#meister)不久前,他在一个博客上解释了字段初始值设定项的来龙去脉,以及静态构造函数是如何很好地使用它们的。这意味着它们会被复制到静态构造函数的开头。
-这是一个非常错误的假设。对于静态构造函数,这种假设不太明显,但对于基于实例的字段和继承,这种假设会导致严重的错误。即使使用静态的CTOR,如果您做出这种天真的假设,某些形式的连接也会失败。一句话:这不是深入的问题。这完全是错误的,以至于有一天你的代码会失败,你不会知道原因。我的原始代码有一个静态的Main方法,这是有效的。因此,除了静态构造函数之外,您还可以使用静态Main方法(有点像构造函数,但在形式上不被认为是构造函数*)*据我所知,@EugeneFedotov:static Main()
不是构造函数(除非该类被称为Main
)。这是一种方法。如果将“主方法”作为应用程序的入口点,则运行时会自动调用它。但它只是一个和其他方法一样的方法。1)不能将静态构造函数定义为public,这将无法编译。2) 在语法错误的构造函数声明末尾没有()导致另一个编译错误。