Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在静态/单例资源引用周围使用块_C#_Singleton_Using - Fatal编程技术网

C# 在静态/单例资源引用周围使用块

C# 在静态/单例资源引用周围使用块,c#,singleton,using,C#,Singleton,Using,这很有趣(无论如何对我来说),我想看看是否有人对这种行为有一个好的答案和解释 假设您有一个单例数据库对象(或静态数据库对象),并将其存储在类Foo中 public class Foo { public static SqlConnection DBConn = new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString); } 然后,假设您已经意识到调用和处理连接的有用性(在本例中,假

这很有趣(无论如何对我来说),我想看看是否有人对这种行为有一个好的答案和解释

假设您有一个单例数据库对象(或静态数据库对象),并将其存储在类Foo中

public class Foo
{
    public static SqlConnection DBConn = new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString);
}
然后,假设您已经意识到调用和处理连接的有用性(在本例中,假设它是一次性使用的,以便于说明)。因此,您决定使用“using”块来处理Dispose()调用

此操作失败,在打开连接的调用上引发异常,声明“ConnectionString属性未初始化”。从app.config/web.config中提取连接字符串不是问题。在调试会话中进行调查时,您会看到Foo.DBConn不是null,而是包含空属性


这是为什么?

可能您的web/app.config中没有相应的ConnectionString节点

<connectionStrings>
<add name="BAR"
     connectionString="Data Source=localhost\sqlexpress;Initial Catalog=mydatabase;User Id=myuser;Password=mypassword;" />


有点离题,没有真正回答您的问题,但是为什么在ADO.NET已经使用连接池的情况下使用单例进行SqlConnection呢?您的代码很可能是这样的:

using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.Connection = conn;
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.CommandText = "SP_YOUR_PROC";
    cmd.ExecuteNonQuery();
}

在您的程序中,少了一件事需要担心:连接生命周期

静态字段在使用之前的某个时间进行评估(不是决定性的)。有关更多详细信息,请参阅。因此,在调用SQL连接时,系统可能还没有准备好创建SQL连接,或者在使用静态字段后,系统甚至可能还没有准备好创建静态字段

此外,在关闭第一个SQL命令后,您将如何处理第二个SQL命令?我不知道SqlConnection是如何工作的,但是在关闭(注意这个cals Dispose)并处理连接之后,静态Foo.DBConn应该消失了,也就是说,它不会被重新评估

如果您想保留您的基本基础结构,我将使用静态属性替换静态字段,该属性在get上返回一个新的SqlConnection:

public static SqlConnection DBConn
{
    get
    {
        return new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString);
    }
}

您错过了原始帖子中关于“(假设此示例为演示目的一次性使用)”的部分@byte您错过了我帖子中关于“静态字段在使用前的某个时间进行评估”的部分。不,我发现了这一点,您错误地将我的评论应用于您的帖子摘要中,而不是你的文章的具体内容。如果你觉得有必要继续,请随时直接给我发信息。这样我就得不到你想要的了。您声明,如果您以非静态方式使用它,它就可以工作,但当您以静态方式使用它时,它就不能工作。我说过静电场在使用前会被评估。为了更详细地了解,实际上,我应该更正确地删除“使用前”部分。我会更新帖子的。不,在那里。如果您使用的是非静态的代码变体,那么它将被证明是有效的。因为这是一个语言奇怪的问题,而不是架构问题:)不过谢谢您的输入。
public static SqlConnection DBConn
{
    get
    {
        return new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString);
    }
}