0

我认为这个问题是 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 变量时,我会得到包含名称和电话值更改的记录列表。例如:

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

4 回答 4

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

于 2015-04-21T10:02:55.840 回答
1

你所说的接近于transactionsc# 对象。c# 中没有对对象事务的固有支持。

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

所以,你现在所能做的就是有一个单独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;
    }
}

Address类使用MemberwiseClone来制作自身的副本。

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

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

克隆人:

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

该示例取自互联网上针对 c#的优秀博客之一

当然,当我指的是对象时,它也适用于List<objects>

于 2015-04-21T10:32:50.860 回答
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
sumi
3
more
1
sumi
3
more

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

于 2017-09-24T08:14:48.510 回答
-1

您可以像这样存储您的第一个列表对象:

List<CSpropr> StoreFirstListInTemp(List<CSpropr> listActionpropr)
{
  List<CSpropr> temp = new List<CSpropr>();
  temp.AddRange(listActionpropr);
  return temp;
}
于 2015-04-21T09:52:48.777 回答