none
请教一个List<自定义类>交换位置的问题 RRS feed

  • 问题

  • 有如下自定义类

        public class test
        {
            public string name { get; set; }
            public string number { get; set; }
            public test Clone()
            {
                return new test()
                {
                    name = this.name,
                    number = this.number
                };
            }
            public void Rep(test m)
            {
                this.name = m.name;
                this.number = m.number;

            }
        }

    执行代码在这里

        List<test> p = new List<test>();
                p.Add(new test() { name = "天上人间", number = "1" });
                p.Add(new test() { name = "海角天涯", number = "2" });
                p.Add(new test() { name = "人民群众", number = "3" });
                p.Add(new test() { name = "粗制滥造", number = "4" });
                p.Add(new test() { name = "风风火火", number = "5" });

                var a = p.FirstOrDefault(t => t.number == "2").Clone();
                var b = p.FirstOrDefault(t => t.number == "3").Clone();
                p.FirstOrDefault(t => t.number == "2").Rep(b);
                p.FirstOrDefault(t => t.number == "3").Rep(a); //若注释此句,则显示内容是正常的,有两个"人民群众",但加上此句,就变得跟没执行过变更顺序一样了

                p.Select((t, i) => 
                    {
                        Console.WriteLine(string.Format("{0}{1}", t.name, t.number));
                        return "";
                    }).Count();

    问题是这样的,我的目的是实现第二项与第三项互换位置,考虑到这是值类型,因此都用了new去生成,以确保不会调用同一个内存块,但为什么执行完后,就像没换过位置一样呢?

    2013年7月3日 13:20

答案

  • N10Z;)

    恐怕并不是string是引用类型的关系。String虽然是引用类型(本质是类),但是已经被经过了特殊处理(譬如运算符重载等)。因此真正原因在于:

     p.FirstOrDefault(t => t.number == "2").Rep(b);:

    执行以后变成了(注意粗、斜黑体部分)

     p.Add(new test() { name = "天上人间", number = "1" });
               p.Add(new test() { name = "人民群众", number = "3" });
                p.Add(new test() { name = "人民群众", number = "3" });
                p.Add(new test() { name = "粗制滥造", number = "4" });
                p.Add(new test() { name = "风风火火", number = "5" });

    但是如果此时执行:p.FirstOrDefault(t => t.number == "3").Rep(a);

    那么找到的是这个黑体的实体类,又改回了原来的样子。

    【解决方案】p.LastOrDefault(t => t.number == "3").Rep(a);  //改成这一句即可


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年7月4日 1:10
    版主

全部回复

  • String 是引用類型 , 值類型的基類一定會有 ValueType

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2013年7月3日 16:09
  • 是的,所以我赋值过去的类都是new出来的,但仍然如此,不明白为什么会这样
    2013年7月3日 23:51
  • N10Z;)

    恐怕并不是string是引用类型的关系。String虽然是引用类型(本质是类),但是已经被经过了特殊处理(譬如运算符重载等)。因此真正原因在于:

     p.FirstOrDefault(t => t.number == "2").Rep(b);:

    执行以后变成了(注意粗、斜黑体部分)

     p.Add(new test() { name = "天上人间", number = "1" });
               p.Add(new test() { name = "人民群众", number = "3" });
                p.Add(new test() { name = "人民群众", number = "3" });
                p.Add(new test() { name = "粗制滥造", number = "4" });
                p.Add(new test() { name = "风风火火", number = "5" });

    但是如果此时执行:p.FirstOrDefault(t => t.number == "3").Rep(a);

    那么找到的是这个黑体的实体类,又改回了原来的样子。

    【解决方案】p.LastOrDefault(t => t.number == "3").Rep(a);  //改成这一句即可


    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年7月4日 1:10
    版主