我正在尝试使用泛型,并且正在尝试创建类似于 Dataset 类的结构。
我有以下代码
public struct Column<T>
{
T value;
T originalValue;
public bool HasChanges
{
get { return !value.Equals(originalValue); }
}
public void AcceptChanges()
{
originalValue = value;
}
}
public class Record
{
Column<int> id;
Column<string> name;
Column<DateTime?> someDate;
Column<int?> someInt;
public bool HasChanges
{
get
{
return id.HasChanges | name.HasChanges | someDate.HasChanges | someInt.HasChanges;
}
}
public void AcceptChanges()
{
id.AcceptChanges();
name.AcceptChanges();
someDate.AcceptChanges();
someInt.AcceptChanges();
}
}
我遇到的问题是,当我添加新列时,我还需要在 HasChanges 属性和 AcceptChanges() 方法中添加它。这只是要求进行一些重构。
所以我想到的第一个解决方案是这样的:
public interface IColumn
{
bool HasChanges { get; }
void AcceptChanges();
}
public struct Column<T> : IColumn {...}
public class Record
{
Column<int> id;
Column<string> name;
Column<DateTime?> someDate;
Column<int?> someInt;
IColumn[] Columns { get { return new IColumn[] {id, name, someDate, someInt}; }}
public bool HasChanges
{
get
{
bool has = false;
IColumn[] columns = Columns; //clone and boxing
for (int i = 0; i < columns.Length; i++)
has |= columns[i].HasChanges;
return has;
}
}
public void AcceptChanges()
{
IColumn[] columns = Columns; //clone and boxing
for (int i = 0; i < columns.Length; i++)
columns[i].AcceptChanges(); //Here we are changing clone
}
}
正如您从评论中看到的那样,我们在结构克隆方面几乎没有问题。对此的简单解决方案是将 Column 更改为类,但从我的测试来看,它似乎将内存使用量增加了约 40%(因为每个对象元数据),这对我来说是不可接受的。
所以我的问题是:有没有人有任何其他想法如何创建可以在不同结构化对象/记录上工作的方法?也许 F# 社区的某个人可以建议如何用函数式语言解决这些问题,以及它如何影响性能和内存使用。
编辑:
sfg 感谢有关宏的建议。
在 Visual Studio 2008 中有一个内置的(但不为人知的)模板引擎,称为 T4。重点是将“.tt”文件添加到我的项目中并创建一个模板,该模板将搜索我的所有类,以某种方式识别记录的那些(例如通过它们实现的某些接口)并使用 HasChanges 和 AcceptChanges 生成部分类( ) 将只调用类包含的列。
一些有用的链接:
VS
博客的 T4 编辑器,包含有关 T4 博客条目的链接和教程,
以及使用 EnvDTE 读取项目文件的示例