在C#中深层复制对象中的Func

时间:2014-03-03 16:23:04

标签: c# .net linq delegates

我正在构建一个单元测试列表,它被组织为一个对象列表,每个对象都包含要作为Func执行的测试方法。每个对象都有一个变量,它在Func的范围内并由它使用。变量不作为参数传入。

迭代列表并运行所有测试运行正常,但可以从一个对象复制一个Func,破坏对该对象的引用,并将其分配给一个新对象?我认为这可能通过创建一个Deep Copy来实现,但是我使用BinaryFormatter的尝试没有用,任何提示都会受到赞赏!

我有一个简化的表单应用程序如下来说明我的问题:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; using
using System.IO;
using System.Linq; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.Text;
using System.Threading.Tasks; using System.Windows.Forms;

namespace WindowsFormsApplication4 {
 public partial class Form1 : Form
 {
     public Form1()
     {
         InitializeComponent();
     }




     public static object DeepClone(object obj)
     {
         object objResult = null;
         using (MemoryStream ms = new MemoryStream())
         {
             BinaryFormatter bf = new BinaryFormatter();
             bf.Serialize(ms, obj);

             ms.Position = 0;
             objResult = bf.Deserialize(ms);
         }
         return objResult;
     }

     [Serializable]
     public class POCOwithFunc {

         public POCOwithFunc(Func<string> myfunc)
         {
             mqi = myfunc;
         }

         public POCOwithFunc() { }

         public Func<string> mqi;

         public object parm;

     }



     private void button1_Click(object sender, EventArgs e)
     {


         List<POCOwithFunc> testList = new List<POCOwithFunc>();

         for (int x = 0; x < 5; x++)
         {

             var pc = new POCOwithFunc();
             pc.parm = x;
             pc.mqi = delegate()
        {
            var rrq = pc.parm;      
            return "result: " + pc.parm;
        };

             testList.Add(pc);
         }

         String output = "";
         foreach (var test in testList)
         {
             output += test.mqi() + "\r\n";
        }
//output:
//result: 0
//result: 1
//result: 2
//result: 3
//result: 4





         var pocoToBeCopied = testList[2];

         var newpoco = new POCOwithFunc();
         newpoco.parm = 10;
         newpoco.mqi = pocoToBeCopied.mqi;

         var res = newpoco.mqi();  //returns 2


         newpoco = (POCOwithFunc)DeepClone(pocoToBeCopied);  //fails

     }

 } }

1 个答案:

答案 0 :(得分:1)

这是我第一次听到深层复制委托(由于委托(Func是委托的类型)包含对其闭包的引用(它的环境,包含该委托的任何变量),因此无效。使用)。

我建议更改参数本身,或者将其作为参数发送(也有一个委托类型:Func<object, string >)。

(而且,我认为你应该考虑重新设计整个事情: - /)