我是一个苦苦挣扎的新手,试图学习并弄清楚这种新的C#语言和OO风格,我的大脑并不像20年前那样敏锐。 这里我们有一个简单的数据库连接到Access(.accdb) 我正在实例化一个辅助类,它包含两个方法,即makeconn和readfrondb方法,如下所示
public void Form1_Load(object sender, EventArgs e) {
Clshelper chelp = new Clshelper();
chelp.makeconn();
chelp.readfromdb();
}
这是下面的帮助类 - 创建因为我想保留连接部分以及我在不同方法中执行的任何类型的数据操作。 但是,除非在方法makeconn中创建连接对象con1的行抛出异常,因为如果我将其编码为con1,则con1是NULL对象。
public class Clshelper {
public OleDbConnection con1;
public OleDbCommand cmd;
public Clshelper() {
Console.WriteLine("instantiated Cls_helper()");
}
public void makeconn() {
OleDbConnection con1 = new OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0; Data Source = D:\\DATA.accdb");
}
public void readfromdb() {
con1.Open();
(...)
}
但是,如果我将makeconn中创建con1连接对象的行放入readfromdb的顶部并且只运行readfromdb,一切正常。 那么为什么readfromdb方法不能"看"我在makeconn方法中创建的con1对象 - 我认为类中的所有变量对于同一个类中的所有方法都是可见的吗?
答案 0 :(得分:2)
该行
OleDbConnection con1 = // ...
实际上在makeconn
函数的范围内创建了一个全新的变量。虽然您有另一个名为con1
的类范围变量,但它们是分开的变量,因此为一个(函数范围的)变量赋值不会将值赋给另一个(类范围的)变量。
修复非常简单。而不是声明一个新变量,只需使用您已在类中声明的那个:
public void makeconn() {
// Don't declare a new variable here:
con1 = new OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0; Data Source = D:\\DATA.accdb");
}
有趣的旁注。如果您有一个与类范围的实例变量命名相同的函数范围变量,则可以使用this
关键字访问类范围的变量:
class MyClass {
private int myVar = 1;
private void myFunc(){
int myVar = 2; // function-scoped myVar overrides class-scoped myVar
int myOtherVar;
myOtherVar = myVar; // myOtherVar = 2 (function-scoped myVar)
myOtherVar = this.myVar; // myOtherVar = 1 (class-scoped myVar)
}
}
答案 1 :(得分:1)
您的帮助程序类无法遵循有关处置连接的良好做法。最终这会导致可用连接耗尽。当发生这种情况时,追踪极其困难。这就是为什么在使用IDisposable对象时需要注意的事项,以确保您已正确处理它们。
这是正确遵循此模式的一种方法:
{{1}}
使用Dapper(此处未显示)进一步简化了它,因此您无需创建命令对象并将结果映射到强类型类中。