为什么cmd在调用了PrepareCommand方法后他的属性都变了?
局部变量不是在其他的方法中不能访问到吗,请说的详细点啊,谢谢!
public static SqlDataReader ExecuteReader(string connectionstring,CommandType cmdType,string cmdText,params SqlParameter[] commandParameters) 
        {
            SqlCommand cmd = new SqlCommand();
            SqlConnection conn = new SqlConnection(connectionstring);            try
            {
                PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
                SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                cmd.Parameters.Clear();
                return rdr;
            }
            catch 
            {
                conn.Close();
                throw;
            }
        }private static void PrepareCommand(SqlCommand cmd,SqlConnection conn,SqlTransaction trans,CommandType cmdType,string cmdText,SqlParameter[] cmdParms) 
        {
            if (conn.State != ConnectionState.Open)
                conn.Open();            cmd.Connection = conn;
            cmd.CommandText = cmdText;            if (trans != null)
                cmd.Transaction = trans;            cmd.CommandType = cmdType;            if(cmdParms != null)
            {
                foreach (SqlParameter parm in cmdParms)
                    cmd.Parameters.Add(parm);
            }
        }

解决方案 »

  1.   

    局部变量在其它的方法中是不可以访问,但是这里的cmd是一个对象,你用对象作为参数来调用PrepareCommand,又因为在C#中对象作为参数,是引用类型的(也就是说,在调用方法时只把cmd在内存中的地址考贝到方法PrepareCommand中,而他们所指向的存储对象数据的内存都是同一块内存),所以当你在方法PrepareCommand中改变了cmd的属性,那么方法ExecuteReader中的cmd的属性也会跟着变。对象在内存中的存储为对象变量-->内存A(存储对象数据的地址)-->内存(存储对象数据)当对象作为参数调用时:参数变量-->内存B(存储对象数据的地址)-->指向上面的 内存(存储对象数据)此时内存B存储的对象数据地址是内存A的一个考贝,也就是说相同,那么内存A和内存B就指向了同一个“存储对象数据的内存”,所以你在方法PrepareCommand中改变了cmd的属性,也就是改变了方法ExecuteReader中的cmd的属性。
      

  2.   

    那string也是引用类型的啊static void Main(string[] args)
            {
                string i="5";
                asd(i);
                Console.WriteLine(i);
                Console.Read();
            } private static void asd(string i)
            {
                i = "asdu";
            }怎么不会输出asdu
      

  3.   

    因为string特殊,在这里它的行为类似基本类型。
    即使是其他引用类型,也不是一定会改变的,看下面这个例子
    static void Main(string[] args)
            {
                DataSet ds=new DataSet();
                asd(ds);
                Console.WriteLine(ds.Tables.Count.ToString());
                bef(ds);
                Console.WriteLine(ds.Tables.Count.ToString());
                Console.Read();
            } private static void asd(DataSet ds)
            {
                DataTable tb = new DataTable();
                ds.Tables.Add(tb);
            }private static void bef(DataSet ds)
            {
                ds = new DataSet();
            }
      

  4.   

    string 是一种特殊的引用类型。
      

  5.   

    string被设计为一个恒常类,它没有提供可以修改它的方法,以避免在做为参数时被修改,每当试图修改一个string,都会生成一个新的string,并将引用指向它。恒常类的问题在于频繁修改时,会带来生成多个对象的开销,所以一般会设计一个伴随类,当频繁修改时,对伴随类的对象进行,最后再转为恒常类的对象,string的伴随类就是stringbuilder,string实现不变的机制类似于上面dataset的例子,只有一点不同,它会检查有无与赋值相同值的string对象,有的话修改引用指向这个相同值,没有的话再创建一个新对象并指向它。