2009-08-17 48 views
3

我想要做的是将IEnumerable传递给一个方法,并让它返回一个IEnumerable的副本。但是,我希望集合中的每一个都是副本,而不仅仅是集合的副本。克隆匿名类型?

一个例子:

// some random data from L2S 
var data = (from p in sourceData 
      select new 
      { 
       a = 1, 
       b = "hello", 
      }).ToArray(); 

var dataCopy = data.Copy(); // somehow i want 'dataCopy' to be a deep copy of 'data' 

foreach (var d in dataCopy) 
{ 
    // alter the item in the collection somehow 
    d.b = d.b + "1"; 
} 

// combine both sets of data 
var finalData = data.Union(dataCopy); 

所以收集 'FinalData的' 有两倍多的项目, '数据' 或 'dataCopy'。因此,'dataCopy'中的所有'b'参数都在末尾附加了“1”,但由于它们仍然引用'data'中的对象,所以'data'中的所有'b'参数也都有“1”结束。

因为这些都是匿名类型,所以我不能简单地使用BinaryFormatter方法'克隆'对象,因为匿名类型是不可序列化的。而且我无法使用Activator.CreateInstance从头创建一个新的,因为匿名类型没有无参数的构造函数。

我意识到我可以通过最初选择我的数据到标记为Serializable的类中来解决这个问题,但是我真的不想修改那么多的代码,因为每次查询数据库时,参数都会不同的...

或者,任何人都可以推荐替代匿名类型?例如:

var data = (from p in sourceData 
      select new SomeSortOfAnonymousTypeReplacement(new 
      { 
       a = 1, 
       b = "hello", 
      })).ToArray(); 

然后它会实现一个可复制的接口?

回答

1

我很好奇,什么样的价值,你认为你会得到了克隆匿名类型。在C#中,所有匿名类型都是不可变的。可以通过改变实例中包含的值来更改它们(例如将值添加到集合中)。但即使通过克隆创建值的浅表副本也不会阻止在现有实例中可见的副作用。

克隆可能对匿名类型具有的唯一值是如果您深入克隆该值。这是匿名类型实例和它的所有内部值的递归克隆。这是一个非常昂贵的操作,可能不是你要找的。

您能否让我们更深入了解您正在努力完成的任务?可能有一个更简单的解决方案。