【问题标题】:asp.net Modify list from FindAll or Where without modifying original list searchedasp.net 从 FindAll 或 Where 修改列表而不修改搜索的原始列表
【发布时间】:2016-12-09 13:38:08
【问题描述】:

我正在尝试从 findall 或 where 创建一个新列表并修改该新列表而不更改原始列表。从 FindAll 创建 list2 并对 list2 进行更改时,它不应影响 list1。怎么会?

编辑...使用了似乎有效的两个答案的组合。有没有预见到的问题???工作代码编辑 编辑...它不起作用。作为对象属性的类没有复制其数据......有什么想法吗???我不明白为什么只是复制或克隆对于列表来说并不简单。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Started");
        List<SampleData> list1 = SampleData.MakeList(3);
        for (int i = 0; i < list1.Count; i++)
        {
            Console.WriteLine("list1.Number => " + list1[i].Number);
            Console.WriteLine("list1.Person => " + list1[i].Person);
        }
        List<SampleData> list2 = new List<SampleData>(list1.FindAll(m => m.Number == 1).Select(x => new SampleData().ShallowCopy())).ToList();
        for (int i = 0; i < list2.Count; i++)
        {
            list2[i].Person = "Person " + list2[i].Number;
            Console.WriteLine("list2.Number => " + list2[i].Number);
            Console.WriteLine("list2.Person => " + list2[i].Person);
        }

        SampleData sd = list2.Find(s => s.Number == 1);
        Console.WriteLine("Apartment Number" + sd.apartment.BuildingLetter); // <<<<------------------- THROWING NULL EXCEPTION FOR APARTMENT

        Console.WriteLine("-------AFTER MODIFYING NEW LIST----LIST1.Person SHOULD BE NULL---");
        for (int i = 0; i < list1.Count; i++)
        {
            Console.WriteLine("--list1.Number => " + list1[i].Number);
            Console.WriteLine("--list1.Person => " + list1[i].Person);
        }
        for (int i = 0; i < list2.Count; i++)
        {
            Console.WriteLine("--list2.Number => " + list2[i].Number);
            Console.WriteLine("--list2.Person => " + list2[i].Person);
        }
        Console.ReadLine();
        System.Environment.Exit(0);
    }

}
class SampleData
{      
    public int Number { get; set; }
    public String Person { get; set; }
    public Apartment apartment { get; set; }
    public static List<SampleData> MakeList(int count)
    {
        List<SampleData> l = new List<SampleData>();
        for (int i = 0; i < count; i++)
        {
            SampleData d = new SampleData();
            d.apartment = new Apartment { RoomNumber = i, BuildingLetter = "letter-" + i };
            d.Number = i;
            l.Add(d);
        }
        return l;
    }
    public SampleData ShallowCopy()
    {
        return (SampleData)this.MemberwiseClone();
    }

}
class Apartment
{
    public int RoomNumber { get; set; }
    public String BuildingLetter { get; set; }
}

【问题讨论】:

  • 显然,当有一个附加类作为属性之一时,这不起作用。作为单独类的属性不会复制其数据。查看编辑后的代码。

标签: asp.net linq list where findall


【解决方案1】:

ShallowCopy 是你的朋友。

像这样在 SampleData 类中定义一个 ShallowCopy() 方法。

class SampleData
{
    public int Number { get; set; }
    public String Person { get; set; }
    public static List<SampleData> MakeList(int count)
    {
        List<SampleData> l = new List<SampleData>();
        for (int i = 0; i < count; i++)
        {
            SampleData d = new SampleData();
            d.Number = i;
            l.Add(d);
        }
        return l;
    }

    public SampleData ShallowCopy()
    {
        return (SampleData)this.MemberwiseClone();
    }

}

然后按如下方式填充list2...

List<SampleData> list2 = new List<SampleData>();
foreach (SampleData sd in list1.Where(m => m.Number == 1))
{
    list2.Add(sd.ShallowCopy());
}

【讨论】:

  • 所以我结合了 shady 和 gthb7 的两个答案。感谢您的输入。我无法识别 AsNoTracking 方法(尝试添加 System.Data.Entity 和 EntityFramework 的引用,但没有显示出来......这看起来更容易和更干净。所以使用了 2 的组合。我没有希望负责添加并记住添加所有属性,因此 ShallowCopy 是对第一个似乎有效的很好的添加。任何可预见的问题???? 使用它的代码我将编辑我的原始帖子
  • 任何可预见的问题?也许。请注意,MemberwiseClone 确实创建了一个浅拷贝,但如果它包含集合,则集合中的项目不会复制(它是具有相同项目的新集合)。
【解决方案2】:

您可以使用 。 AsNoTracking() 方法在从 DbContext 或 ObjectContext

中选择时 Entity Query
List<SampleData> list2 = new List<SampleData>(list1.Where(m => m.Number == 1).AsNoTracking().ToList());

或使用类似的复制承包商

class SampleData
{
    public int Number { get; set; }
    public String Person { get; set; }

    public SampleData(SampleData obj)
    {
        This.Number=obj.Number;
        This.Person=obj.Person;
        ..
        ..
    }
    public static List<SampleData> MakeList(int count)
    {
        List<SampleData> l = new List<SampleData>();
        for (int i = 0; i < count; i++)
        {
            SampleData d = new SampleData();
            d.Number = i;
            l.Add(d);
        }
        return l;
    }
}

然后

 List<SampleData> list2 = new List<SampleData>(list1.Where(m => m.Number == 1).Select(x=>new SampleData(x)).ToList());

【讨论】:

  • 这个 SampleData 类的列表是一个非常小的属性类。这对于一个小类来说很容易,但对于一个大类来说,有更多的属性。有没有一种更简单的方法来获取所有属性,而无需在选择中指定每个属性。那么该项目的所有属性都被复制了吗?
猜你喜欢
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2014-07-10
  • 2018-05-27
相关资源
最近更新 更多