请先看程序:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;namespace Refesh
{
class Program
{
static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("server=localhost;DataBase=ABC;uid=sa;pwd=password;");
DataTable dt = new DataTable("ABC");
setConn(conn);
Console.WriteLine(conn.ConnectionString);
setConn(ref conn);
Console.WriteLine(conn.ConnectionString);
setDataTable(dt);
Console.WriteLine(dt.TableName);
setDataTable(ref dt);
Console.WriteLine(dt.TableName);
Console.ReadLine();
} static void setDataTable(DataTable dt)
{
dt = null;
dt = new DataTable("XYZ");
}
static void setDataTable(ref DataTable dt)
{
dt = null;
dt = new DataTable("XYZ");
}
static void setConn (SqlConnection conn)
{
conn = null;
conn = new SqlConnection("server=localhostSSS;DataBase=XYZ;uid=saS;pwd=XXX;");
}
static void setConn(ref SqlConnection conn)
{
conn = null;
conn = new SqlConnection("server=localhostSSS;DataBase=XYZ;uid=saS;pwd=XXX;");
}
}
}
想一下会输出什么结果....
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;namespace Refesh
{
class Program
{
static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("server=localhost;DataBase=ABC;uid=sa;pwd=password;");
DataTable dt = new DataTable("ABC");
setConn(conn);
Console.WriteLine(conn.ConnectionString);
setConn(ref conn);
Console.WriteLine(conn.ConnectionString);
setDataTable(dt);
Console.WriteLine(dt.TableName);
setDataTable(ref dt);
Console.WriteLine(dt.TableName);
Console.ReadLine();
} static void setDataTable(DataTable dt)
{
dt = null;
dt = new DataTable("XYZ");
}
static void setDataTable(ref DataTable dt)
{
dt = null;
dt = new DataTable("XYZ");
}
static void setConn (SqlConnection conn)
{
conn = null;
conn = new SqlConnection("server=localhostSSS;DataBase=XYZ;uid=saS;pwd=XXX;");
}
static void setConn(ref SqlConnection conn)
{
conn = null;
conn = new SqlConnection("server=localhostSSS;DataBase=XYZ;uid=saS;pwd=XXX;");
}
}
}
想一下会输出什么结果....
解决方案 »
- 这段代码运行的时候出错了,一直不知道问题出在哪,望高手指点!
- 请问如何快速找出DataTable中相同的记录
- 帮忙看下哪错了,谢谢!
- 如何屏蔽WebBrowser控件ScriptError对话框?
- 运行时动态切换窗口ICON图标,到底有多少种方法?50分 求宝贵意见!谢谢谢谢谢谢
- 急!将DataGrid中数据导出到Excel时,01001变为1001,该怎么处理
- 关于窗体背景图片问题。(注:WinForm)多谢
- 如何在c#中利用模板生成word,并生成word目录?
- 程序操作263企业邮箱的SMTP邮件服务器的问题
- 在WebService中利用客户证书进行身份验证的问题!急!!参与有分!
- C#.net 2005 多线程问题
- 关于datatable中的rowchanged事件
public void Change(int input)和public void Change(ref int input)这样就有区别第一个传值,在方法体内改变不了input的值,而后者传引用,可以在方法体内更改input的值
static void setDataTable(DataTable dt)
{
dt = null;
dt = new DataTable("XYZ");
}Change to
static void setDataTable(DataTable dt)
{
dt.TableName="XYZ";
}
在这个里面new了
去掉....同样不影响执行结果..
(为了容易表达,我暂且命名存放在堆中的内容为堆中对象,存放在栈上的内容为栈中对象。)
值类型存放在栈中,直接访问。如果有:int a=0;int b=a;就产生了两个栈中对象。
引用类型需要在堆中显式分配,且不能直接访问,需要在栈中分配一个栈中对象(C++叫指针,C#叫引用)指向其堆中对象。
如果:
StringBuilder strb = new StringBuilder();
StringBuilder strb2 = strb;
则在堆中只有一个堆中对象,只是栈中有两个栈中对象指向堆中对象。
可以看出:每个变量都是一个栈中对象。不管是值类型还是引用类型,只是值类型的栈中对象就是其内容,而引用类型的栈中对象只是一个指向堆中对象的地址。参数传递分值传递和引用传递两种。
通常,在没有显式指出ref和out时都是值传递。值传递:传的是对象的值拷贝。(即函数内参数对象是调用时传递的对象的栈中对象的拷贝。)
引用传递:传的是栈中对象的地址。(即函数内参数对象与调用时传递的对象完全是同一栈中对象。)
现在用例子来说明传值跟传地址的不同:
private void button2_Click(object sender, System.EventArgs e)
{
StringBuilder strb1 = new StringBuilder();
StringBuilder strb2 = new StringBuilder();
Test1(strb1);
Test2(ref strb2);
string str1 = strb1.ToString(); //str1值:"A"
string str2 = strb2.ToString(); //str2值:"BC"
}void Test1(StringBuilder strb)
{
//strb和strb1是两个栈中对象,但指向相同的地址,这个操作是改变堆中对象
strb.Append("A"); //这里将strb指向一个新的堆中对象,所以后面的操作与strb1指向的栈中对象无关
strb = new StringBuilder("B");
strb.Append("C");
}void Test2(ref StringBuilder strb)
{
//这里的strb和strb2是同一个栈中对象,所以改变strb的值使其指向另一个对象也等于改变strb2
strb = new StringBuilder("B");
strb.Append("C");
}
把上面的代码精减了...
请先测试...再说原因
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;namespace Refesh
{
class Program
{
static void Main(string[] args)
{
DataTable dt1 = new DataTable("初始表名");
DataTable dt2 = new DataTable("初始表名");
Console.WriteLine("初始表名相同"); setDataTable(dt1);
Console.WriteLine("执行不带ref的方法,结果为: " + dt1.TableName);
setDataTable(ref dt2);
Console.WriteLine("执行带ref的方法,结果为: " + dt2.TableName);
Console.ReadLine();
} static void setDataTable(DataTable dt)
{
dt = new DataTable("新表名");
}
static void setDataTable(ref DataTable dt)
{
dt = new DataTable("新表名");
}
}
}
ref object 相当于指向指针的指针,就是说你可以修改object的地址
object 指针,你只能修改object的值,却不能修改它的指向
下面的示例演示通过值向 Change 方法传递引用类型的参数 arr。由于该参数是对 arr 的引用,所以有可能更改数组元素的值。但是,试图将参数重新分配到不同的内存位置时,该操作仅在方法内有效,并不影响原始变量 arr。C# 复制代码
class PassingRefByVal
{
static void Change(int[] pArray)
{
pArray[0] = 888; // This change affects the original element.
pArray = new int[5] {-3, -1, -2, -3, -4}; // This change is local.
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
} static void Main()
{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]); Change(arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
}
} 输出
Inside Main, before calling the method, the first element is: 1 Inside the method, the first element is: -3 Inside Main, after calling the method, the first element is: 888 代码讨论
在上个示例中,数组 arr 为引用类型,在未使用 ref 参数的情况下传递给方法。在此情况下,将向方法传递指向 arr 的引用的一个副本。输出显示方法有可能更改数组元素的内容,在这种情况下,从 1 改为 888。但是,在 Change 方法内使用 new 运算符来分配新的内存部分,将使变量 pArray 引用新的数组。因此,这之后的任何更改都不会影响原始数组 arr(它是在 Main 内创建的)。实际上,本示例中创建了两个数组,一个在 Main 内,一个在 Change 方法内。示例:通过引用传递引用类型
本示例除在方法头和调用中使用 ref 关键字以外,其余与上个示例相同。方法内发生的任何更改都会影响调用程序中的原始变量。C# 复制代码
class PassingRefByRef
{
static void Change(ref int[] pArray)
{
// Both of the following changes will affect the original variables:
pArray[0] = 888;
pArray = new int[5] {-3, -1, -2, -3, -4};
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
}
static void Main()
{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]); Change(ref arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
}
}
比如:
void func1()
{
Class1 a = new Class1();
a.Property1 = 0;
this.func2(a);
Console.WriteLine(a.Property1);
}
void func2(Class1 a)
{
a = new Class1();
a.Property1 = 10;
}输出仍然为0。如果func2使用了ref那么输出就为10。