ormlite-servicestack,C#,Types,ormlite Servicestack" /> ormlite-servicestack,C#,Types,ormlite Servicestack" />

如何在c#中克隆T型?

如何在c#中克隆T型?,c#,types,ormlite-servicestack,C#,Types,ormlite Servicestack,我有一个类型Foo,如下所示: [Alias("Boo")] public class Foo { public int Id { get; set; } public string Name { get; set; } } 我正在保存对象属性更改的历史记录,出于性能原因,我想创建第二个表,用于推送所有历史记录。不幸的是,OrmLite不支持(afaik)每种类型的多个表。定义时将仅使用别名而不是类型名称 由于我使用的是通用数据控制器,我需要克隆实际类型(使用不同的名称)。我不需要在这

我有一个类型
Foo
,如下所示:

[Alias("Boo")]
public class Foo
{
  public int Id { get; set; }
  public string Name { get; set; }
}
我正在保存对象属性更改的历史记录,出于性能原因,我想创建第二个表,用于推送所有历史记录。不幸的是,OrmLite不支持(afaik)每种类型的多个表。定义时将仅使用别名而不是类型名称


由于我使用的是通用数据控制器,我需要克隆实际类型(使用不同的名称)。我不需要在这两种类型之间转换/强制转换对象,但如果这也是可能的话,这将非常有用。

您能否添加并实现
IClonable

接口可克隆
{
T克隆();
}
[别名(“Boo”)]
公共类Foo:ICloneable
{
公共int Id{get;set;}
公共字符串名称{get;set;}
public Foo Clone(){…}
}

您可以使用继承来克隆定义

克隆实例非常模糊:它是深度克隆还是浅层克隆?如果很深,有多深?它会包括对其他可能的POCO的引用吗?如果是,它将如何包括它们?使用身份证?使用副本

此外,将对象的完整副本存储在不同的表中并不是实现历史记录的方法

如果我是你,我会有一个不同的类型来及时存储序列化的更改,然后在你的实体中有一个更改列表

这就是我在最近的一些项目的POCOs中实现它的方式(使用实体框架进行持久化,根据需要对OrmLite进行调整…同时删除一些内容):

然后为需要存储历史记录的实体创建一个基本实体(或一个接口,我使用基本实体,因为我不需要额外的多重继承,并且可以避免在所有类中写入相同的属性):

public abstract class BaseTrackedEntity : BaseEntity, IAuditableEntity, IChangeTrackedEntity
{
  /* ... Other properties removed for clarity ... */
  public ICollection<EntityHistory> Histories { get; set; }
}
公共抽象类BaseTrackedEntity:BaseEntity、IAuditableEntity、IChangeTrackedEntity
{
/*…为清晰起见,删除了其他属性*/
公共ICollection历史记录{get;set;}
}
然后您的实体将继承自
BaseTrackedEntity

在持久化对数据库的更改后,您将发现从加载的实体到保存的实体的更改(在EF中很容易,它为您提供了一个
更改集
,不知道OrmLite,但如果它没有提供方法,您可以使用反射来解决),并将它们序列化到
EntityHistory
实例(在
OldValues
NewValues
中)并将其添加到
Histories
列表中。我使用JSON,但您可以使用任何东西


这既可以用于日志记录目的(我没有复制我的日志记录属性,例如
User
CreationTime
,等等),但它们将位于
BaseTrackedEntity
)上,也可以用于
撤消
EntityHistory
组中的
TransactionId
,如果需要的话),性能相当好(比每次更新一次克隆和存储整个对象要简单得多)而且易于实现和维护。

解决方案变得比我想象的要简单——尽管我一开始没有想到:继承

由于我无法控制
Foo
类,因此我无法手动编写一个新类型来反映它(成员可能会在
Foo
中更改)。创建一个继承自
Foo
的新类型
Boo
,而不定义额外成员,将允许使用OrmLite使用新名称进行转换和创建表

public class Foo
{
  public int Id { get; set; }
  public string Name { get; set; }
}

public class Boo : Foo
{

}

只是一个警告,当你说
Clone
时,它有时是模棱两可的,因为不清楚它是深层拷贝还是浅层拷贝。甚至说“我们建议不要在公共API中实现ICloneable。”我不想克隆实例。我需要克隆类型定义。你知道继承吗?创建一个从你想要克隆定义的类型继承的类型,而不定义更多的成员,这可能是我没有想到的!但这是一个完美的解决方案(继承)!编辑您的答案,我会接受它,因为当前的答案有点不正确。因此,每当您更改
类Foo
,您都希望存在一个
类Boo
,其中包含相同的属性,保存一些容易出错的手动键入?某种程度上,我无法控制原始类,另外一些类是在运行时生成的同样,在我无法控制的地方(我猜它使用的是CodeDOM)
public abstract class BaseTrackedEntity : BaseEntity, IAuditableEntity, IChangeTrackedEntity
{
  /* ... Other properties removed for clarity ... */
  public ICollection<EntityHistory> Histories { get; set; }
}
public class Foo
{
  public int Id { get; set; }
  public string Name { get; set; }
}

public class Boo : Foo
{

}