根据我读过的其他帖子,这似乎不可能,但我想我会发布我正在尝试做的事情,看看是否有人知道解决方案。
我正在尝试将“Clone()”方法添加到从 Telerik 开放访问域模型生成的类中。没问题。我能够弄清楚如何将基类添加到生成的实体模型中,以便我可以通过基类来识别这些类。 (所有实体都继承自基类)
我希望所有这些实体模型类都能够克隆自身。我也找到了解决方案。 (深度克隆对象)
现在我有一个基类,我想向从该基类派生的每个类添加 Clone() 函数。所以......看起来基类是放置它的自然位置......对吧?
public abstract class DBEntityBase
{
/// <summary>
/// Gets a COPY of the instance in it's current state
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
protected T Clone<T>()
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(this));
}
}
我添加受保护的通用克隆()方法,因为在基类级别我们不知道我们正在克隆的类型。 Clone() 方法需要由实体模型本身实现,以提供要克隆的特定类型。
public partial class DeliverableEntity
{
public new DeliverableEntity Clone()
{
return this.Clone<DeliverableEntity>();
}
}
这工作正常,但不保证派生类将公开公开 Clone() 方法,因此我添加了一个抽象克隆()方法到基地这将require派生类实现公共 Clone() 方法。
public abstract class DarkRoomDBEntityBase
{
/// <summary>
/// Gets a COPY of the instance in it's current state
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
protected T Clone<T>()
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(this));
}
/// <summary>
/// Gets a deep COPY of the entity instance
/// </summary>
/// <returns></returns>
public abstract DBEntityBase Clone();
}
我给它一个基类本身的返回类型;每个实现都必须返回一个遵循 DBEntityBase 的值,当然,所有派生类都会这样做。由于 Clone() 方法返回派生类本身的类型,那么……这似乎是有道理的。
DeliverableEntity originalEntity = new DeliverableEntity();
DeliverableEntity clonedEntity = originalEntity.Clone();
然而,在构建时,我收到错误..
“DeliverableEntity”未实现继承的抽象成员
'DBEntityBase.Clone()'
大概是由于返回类型。
我知道我可以将 Clone() 方法放在一个单独的实用程序类中,而不是直接在每个实体模型中实现它......这将使我解决我的问题(并且可能节省大量实现代码),但我是仍然想知道为什么这行不通。似乎应该有办法做到这一点。
UPDATE
为了回应@Luann的第一个回复(谢谢),我将其更改为“覆盖”......
public partial class DeliverableEntity
{
public override DeliverableEntity Clone()
{
return this.Clone<DeliverableEntity>();
}
}
现在收到以下错误...
返回类型必须是“DBEntityBase”以匹配重写的成员
'DBEntityBase.Clone()'
SOLUTION
感谢 Flynn1179,我能够再次前进。我想我应该花点时间记录一下我在这里所做的事情以供将来参考。
我没有为 ORM 中的每个实体模型创建一个分部类来实现抽象方法,而是按照建议创建了一个扩展方法。
namespace DAL
{
public partial class DeliverableEntity : DBEntityBase
{
// ... Code generated from ORM
}
public partial class DeliverableItemEntity : DBEntityBase
{
// ... Code generated from ORM
}
public partial class DeliverableItemAttrEntity : DBEntityBase
{
// ... Code generated from ORM
}
}
namespace DAL
{
public static class EntityExtensionMethods
{
public static T Clone<T>(this T entity) where T: DBEntityBase
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(entity));
}
}
}
有些事情需要注意...
- 将此类放在与实体模型相同的命名空间中。如果它位于不同的命名空间中,那么您将需要添加该命名空间才能访问该方法。
- 我将泛型类型的约束定义为仅所有继承该类型的类数据库实体库班级。由于我使所有实体模型类都从这个基类派生,我知道它们都将公开此方法,而且任何不从此类派生的类都不会具有此功能。
- 扩展方法和包含它的类必须是static
现在最酷的部分是所有实体都可以访问该功能......
// Create the original instances of the entities
DeliverableEntity origDeliverable = new DeliverableEntity();
DeliverableItemEntity origItem = new DeliverableItemEntity();
DeliverableItemAttrEntity origItemAttr = new DeliverableItemAttrEntity();
// now here's the magic
DeliverableEntity cloneDeliverable = origDeliverable.Clone();
DeliverableItemEntity cloneItem = origItem.Clone();
DeliverableItemAttrEntity cloneItemAttr = origItemAttr.Clone();
我喜欢这个解决方案,因为它具有基类的简单性,其中实现是在单个位置定义的(而我正在考虑在每个派生类中单独实现抽象方法),而且它与 DBEntityBase 类相关联并且在同一位置命名空间,它成为基类定义的“契约”的一部分,这意味着只要我有一个从 DBEntityBase 派生的类,我就可以指望它可用。