C#:为什么';这项静态作业不管用吗?

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

我得到错误“name\u client在当前上下文中不存在。”与“database”变量相同

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) 在语法错误的构造函数声明末尾没有()导致另一个编译错误。