假设我有一些已知的库来从.xls文件加载数据,并返回一个DataTable,其中填充了来自任何excel工作簿中第一个工作表的数据.还有一个Log函数,可以在没有工作调试器的情况下打印出消息.
DataTable dtFoo = null;
DataTable dtBar = null;
DataTable dtChaz = null;
String[] files = new String[]{ "file1.xls", "file2.xls", "file2.xls" };
DataTable[] dts = new DataTable[] { dtFoo, dtBar, dtChaz };
for(int i = 0; i < 3; i++)
{
dts[i] = SomeLibrary.LoadFromFile(files[i]); //Returns a new DataTable
Log((dts[i] == null) + " " + dts[i].Rows.Count)
}
Log((dts[0] == null) + " " + (dtFoo == null));
Log((dts[1] == null) + " " + (dtBar == null));
Log((dts[2] == null) + " " + (dtChaz == null));
Run Code Online (Sandbox Code Playgroud)
Log Output:
False 40
False 455
False 34
False True
False True
False True
Run Code Online (Sandbox Code Playgroud)
很明显,在使用我无法弄清楚的引用类型变量时,我遗漏了一些重要的东西.循环完成后,为什么我的DataTable变量仍然为null?
这一行:
DataTable[] dts = new DataTable[] { dtFoo, dtBar, dtChaz };
Run Code Online (Sandbox Code Playgroud)
...不会使用数组元素对变量进行别名,就像您认为的那样.它只是创建新的数组,并设置初始值到的值dtFoo,dtBar并dtChaz分别(所有这些都是零).之后,数组和变量完全分开.
如果您想稍后设置变量,则需要:
dtFoo = dts[0];
dtBar = dts[1];
dtChaz = dts[2];
Run Code Online (Sandbox Code Playgroud)
当然这不一定是DataTables.简单的例子:
string x = "initial";
string[] array = new string[] { x };
array[0] = "modified";
Console.WriteLine(x); // "initial"
x = array[0];
Console.WriteLine(x); // "modified"
Run Code Online (Sandbox Code Playgroud)
请注意,这是您更改数组元素的值时.相反,如果您修改值引用的对象,那就是另一回事:
StringBuilder builder = new StringBuilder("123");
StringBuilder[] array = new StringBuilder[] { builder };
builder[0].Append("456");
Console.WriteLine(builder); // 123456
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅有关引用类型和值类型的文章.基本上,您需要区分引用和它们引用的对象.
| 归档时间: |
|
| 查看次数: |
879 次 |
| 最近记录: |