保留对象实例的值

时间:2015-04-21 09:39:48

标签: c# preserve

我认为这个问题是面向对象语言(如C#)中的值/引用实例化问题。但我是新手,我不知道如何扭亏为盈。

我有一个使用这段代码的方法:

    List<CSpropr> listActionpropr = CSpropr.searchList(actionCondition); // Get a list of all records of table PROPR for the 'actioncondition' specified
// For each record...
    foreach (CSpropr instance in listActionpropr)
       {
         instance.ValName = "John";
         instance.ValPhone = 323234232;
         instance.update(); // This make and UPDATE of the record in DB
       }

稍后在同一方法中,我想在更新之前使用listActionpropr的第一个版本。做一种回滚。但是当我迭代listActionpropr变量时,我得到了Name和Phone值变化的记录列表。 例如:

foreach (CSApropr instance1 in listActionpropr )
    {
      instance1.update();
    }

是否有一种优雅的方法来保留价值而不创建对其他变量的新搜索?像这样:

List<CSpropr> listActionpropr = CSpropr.searchList(actionCondition); // Get a list of all records of table PROPR for the 'actioncondition' specified
List<CSpropr> preservedList = CSpropr.searchList(actionCondition); // Get a list of all records of table PROPR for the 'actioncondition' specified
    // For each record...
        foreach (CSpropr instance in listActionpropr)
           {
             instance.ValName = "John";
             instance.ValPhone = 323234232;
             instance.update(); // This make and UPDATE of the record in DB
           }
....

foreach (CSApropr instance1 in preservedList )
        {
          instance1.update();
        }      

4 个答案:

答案 0 :(得分:1)

根据这个答案,我会在这种情况下使用DeepClone进行序列化:https://stackoverflow.com/a/519512/841467

我在LinqPad的快速实施是:

void Main()
{
    List<CSpropr> listActionpropr = CSpropr.searchList("act"); // Get a list of all records of table PROPR for the 'actioncondition' specified
    List<CSpropr> preservedList = listActionpropr.DeepCopy(); // Get a list of all records of table PROPR for the 'actioncondition' specified
    // For each record...
    foreach (CSpropr instance in listActionpropr)
    {
        instance.ValName = "John";
        instance.ValPhone = 323234232;
        instance.update(); // This make and UPDATE of the record in DB
    }

    foreach (CSpropr instance1 in preservedList )
    {
        instance1.update();
    }
}

// Define other methods and classes here
[Serializable]
public class CSpropr {
    public string ValName {get;set;}
    public int ValPhone {get;set;}

    public void update() {
        ValName.Dump();
        ValPhone.Dump();
    }

    public static List<CSpropr> searchList(string act) {
        return new List<CSpropr> { new CSpropr {ValName = "First", ValPhone = 4444} , new CSpropr {ValName = "First", ValPhone = 4444 }};   
    }
}

public static class GenericCopier
{
    public static T DeepCopy<T>(this T original) where T : class
    {
        using (MemoryStream memoryStream = new MemoryStream())
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(memoryStream, original);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return (T)binaryFormatter.Deserialize(memoryStream);
        }
    }
}

结果是:

John 323234232 John 323234232 First 4444 First 4444

答案 1 :(得分:1)

您所谈论的内容接近于c#对象中的transactions。 c#中的对象事务没有固有的支持。

Microsoft确实在STM(软件事务内存)上启动了一个项目,以支持.NET对象的transaction功能。但是,由于各种原因,该项目已经退役。

因此,您现在可以做的就是为原始列表单独object。 您可以使用其他答案中描述的某个帮助方法DeepCopy IClonable对象,或者为您的对象实现public class Person : ICloneable { public string LastName { get; set; } public string FirstName { get; set; } public Address PersonAddress { get; set; } public object Clone() { Person newPerson = (Person)this.MemberwiseClone(); newPerson.PersonAddress = (Address)this.PersonAddress.Clone(); return newPerson; } } 接口,它为您执行深层复制。一个例子是:

public class Address : ICloneable
{
    public int HouseNumber { get; set; }
    public string StreetName { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

地址类使用 MemberwiseClone 制作自己的副本。

Person herClone = (Person)emilyBronte.Clone();

克隆人:

List<objects>

该示例来自互联网上用于c#

的优秀blogs之一
  

当然,当我指的是对象时,它也适用于{{1}}。

答案 2 :(得分:0)

基本上你需要两个相同的列表,但是如果你改变list1的一个元素,它不应该影响list2的相同元素。 您可以通过各种方式执行此操作:例如,使用序列化。

以下代码将显示我的方式:

模块模块1

Sub Main()

    Dim listone As New List(Of demo) 'first list
    Dim listwo As New List(Of demo)   ' second list
    Dim var1 As Integer
    Dim var2 As String
    Dim obj As New demo()           'first object created in list-1
    obj.id = 1
    obj.name = "sumi"
    listone.Add(obj)                'first object inserted in the list-1
    Dim obj1 As New demo()
    obj1.id = 3
    obj1.name = "more"
    listone.Add(obj1)               'Second object inserted in the list-1
    For Each w In listone
        Dim obj3 As New demo()
        var1 = w.id
        obj3.id = var1
        var2 = w.name
        obj3.name = var2
        listwo.Add(obj3)            'looping all objects of list-1 and adding them in list-2 .Hence making both lists identical

    Next
    For Each p In listone      'making change in the list-1 and this change should not be refelected in list-2
        If (p.id = 1) Then
            p.id = 5
        End If
    Next
    For Each z In listone
        Console.WriteLine(z.id)
        Console.WriteLine(z.name)

    Next
    For Each q In listwo
        Console.WriteLine(q.id)
        Console.WriteLine(q.name)
    Next
    Console.ReadLine()

End Sub
Class demo
    Public name As String
    Public id As Integer
End Class

结束模块

输出:
5
碳黑
3

1
碳黑
3

因此无论原始列表中的更改如何,克隆列表都不会受到影响

答案 3 :(得分:-1)

您可以存储第一个列表对象:

List<CSpropr> StoreFirstListInTemp(List<CSpropr> listActionpropr)
{
  List<CSpropr> temp = new List<CSpropr>();
  temp.AddRange(listActionpropr);
  return temp;
}