我理解c#(一): 参数传递和变量复制之间的关系

来源:互联网 发布:淘宝书店货源 编辑:程序博客网 时间:2024/06/07 00:07

1.当参数是值类型与引用类型的区别和联系

2.当参数string的时候与值类型的区别

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleCSharp
{
    class classtest
    {
        public int test;
        public string str;
        public classtest()
        {
            test = 0;
            str = "";
        }
    }
    struct structtest
    {
        public int test;
        public string str;
    }
    class Program
    {
        // ==与Equals一致,对值类型比较的是值相等,对于引用类型比较的是两地址是否相等
        //  对于预定义的值类型,如果操作数的值相等,则相等运算符       (==)       返回真,否则,返回假。
        //  对于除       string       类型以外的引用类型,如果两个操作数引用相同的对象,则       ==       返回真。
        // 对于       string       类型,==       将比较字符串的值。

        //  public static bool ReferenceEquals( object left, object right );
        //这个函数就是判断两个引用类型对象是否指向同一个地址。有此说明后,就确定了它的使用范围,即只能对于引用类型操作。
        //那么对于任何值类型数据操作,即使是与自身的判别,都会返回false。这主要因为在调用此函数的时候,值类型数据要进行装箱操作

        static void Main(string[] args)
        {
            classtest ct = new classtest();
            changeValue(ct);
            classtest ct1 = ct;
            Console.WriteLine("class : {0} {1} {2}", ct1 == ct, ct1.Equals(ct), object.ReferenceEquals(ct1, ct)); //True  True
            Console.WriteLine("{0} {1}", ct.test, ct.str);
            // 首先在C#中传递方法参数缺省是“值拷贝”模式,也就是说对于值类型(ValueType)变量直接拷贝一份,
            // 而对于引用类型则拷贝一个指向同一对象的引用副本传递给方法,因此即使不使用ref关键字,
            // 我们也可以在方法内部改变该引用所指向对象的内部状态

            structtest st = new structtest();
            changeValue(st);
            structtest st1 = st;
            Console.WriteLine("struct : {0} {1} ", st1.Equals(st), object.ReferenceEquals(st1, st));
            Console.WriteLine("{0} {1}", st.test, st.str);

            int i = 0;
            int j = i;
            Console.WriteLine("int : {0} {1} {2}", i == j, i.Equals(j), object.ReferenceEquals(i, j));
            changeValue(i);
            Console.WriteLine(i);

            string ss = "ss";
            string ss2 = ss;
            Console.WriteLine("string {0} {1} {2}", ss2 == ss, ss2.Equals(ss), object.ReferenceEquals(ss2, ss));
            changeValue(ss);
            Console.WriteLine(ss);
            // string对象保存在堆上而不是堆栈上,是引用类型的,因而当把一个字符串变量赋给另一个字符串时,
            // 会得到对内存中同一个字符串的两个引用.
            //然后,修改其中一个字符串,注意这会创建一个完全新的string对象,而另一个字符串没改变!

        }
        static void changeValue(classtest t)
        {
            t.test += 100;
            t.str += "class";
        }
        static void changeValue(int i)
        {
            i += 100;
        }
        static void changeValue(string i)
        {
            i += "string";
        }
        static void changeValue(structtest t)
        {
            t.test += 200;
            t.str += "struct";
        }

    }
}

原创粉丝点击