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

在C中的对象中深度复制Func#,c#,.net,linq,delegates,C#,.net,Linq,Delegates,我正在构建一个单元测试列表,它被组织为一个对象列表,每个对象都包含要作为Func执行的测试方法。每个对象都有一个变量,该变量在Func的作用域内并由其使用。变量未作为参数传入 迭代列表并运行所有测试运行良好,但是否可以从一个对象复制Func,-断开对该对象的引用-,并将其分配给新对象?我假设通过创建深度副本,这是可能的,但我使用BinaryFormatter的尝试没有成功,任何提示都将不胜感激 我有一个简化的表单应用程序,如下所示来说明我的问题: using System; using Sys

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

迭代列表并运行所有测试运行良好,但是否可以从一个对象复制Func,-断开对该对象的引用-,并将其分配给新对象?我假设通过创建深度副本,这是可能的,但我使用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

     }

 } }
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;使用
使用System.IO;
使用System.Linq;
使用System.Runtime.Serialization.Formatters.Binary;
使用系统文本;
使用System.Threading.Tasks;使用System.Windows.Forms;
命名空间Windows窗体应用程序4{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
公共静态对象DeepClone(对象obj)
{
objectobjresult=null;
使用(MemoryStream ms=new MemoryStream())
{
BinaryFormatter bf=新的BinaryFormatter();
bf.序列化(ms,obj);
ms.Position=0;
objResult=bf.反序列化(ms);
}
返回objResult;
}
[可序列化]
公共类POCOwithFunc{
公共POCOwithFunc(Func myfunc)
{
mqi=myfunc;
}
公共POCOwithFunc(){}
公共职能mqi;
公共对象参数;
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
List testList=新列表();
对于(int x=0;x<5;x++)
{
var pc=new POCOwithFunc();
pc.parm=x;
pc.mqi=delegate()
{
var rrq=pc.parm;
返回“结果:”+pc.parm;
};
testList.Add(pc);
}
字符串输出=”;
foreach(testList中的var测试)
{
输出+=test.mqi()+“\r\n”;
}
//输出:
//结果:0
//结果:1
//结果:2
//结果:3
//结果:4
var pocoToBeCopied=testList[2];
var newpoco=new POCOwithFunc();
newpoco.parm=10;
newpoco.mqi=pocoToBeCopied.mqi;
var res=newpoco.mqi();//返回2
newpoco=(POCOwithFunc)DeepClone(pocoToBeCopied);//失败
}
} }

这是我第一次听说委托的深度复制(这不起作用,因为委托(Func是委托的类型)包含对其闭包(其环境,其中包含该委托正在使用的任何变量)的引用)

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


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

当你说“它没用”时到底发生了什么?你收到错误消息了吗?是什么?我会试试的iCloneable@Alex看看它说了些什么……没有标记为可序列化。如果你深度克隆一个
Func
,这难道不意味着你试图在该
Func
中保留一些状态吗?
Func
在设计上不应该是无状态的吗?@RoberHarvey我想保留对func的封闭/外部对象中变量的引用,而不是该变量的特定值。您可以克隆一个func,这很好,但我接受您关于重新设计的观点:func newfunc=delegate(){return“clone me”;};var clonedfunc=(func)DeepClone(newfunc);好吧,正如我写的为什么它不起作用——我意识到它会起作用,但是——闭包也会被克隆,没有能力将委托“附加”到新对象上(实际上,这将使对闭包的任何更改都不可能)