Gar*_*rom 8 c# inheritance base-class
基于我读过的其他帖子,似乎这可能是不可能的,但我想我会发布我想要做的事情,看看是否有人知道解决方案.
我正在尝试向Telerik Open Access域模型生成的类添加"Clone()"方法.没问题.我能够弄清楚如何将基类添加到生成的实体模型中,以便我可以通过它们的基类来识别这些类.(所有实体都从基类继承)
我希望所有这些实体模型类能够克隆自己.我也找到了解决方案.(深度克隆对象)
现在我有一个基类,我想在每个从该基类派生的类中添加一个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));
}
}
Run Code Online (Sandbox Code Playgroud)
我添加了受保护的泛型Clone()方法,因为在基类级别我们不知道我们正在克隆的类型.Clone()方法需要由实体模型本身实现,以便提供克隆的特定类型.
public partial class DeliverableEntity
{
public new DeliverableEntity Clone()
{
return this.Clone<DeliverableEntity>();
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但不保证派生类将公开公开Clone()方法,因此我向基础添加了一个抽象Clone()方法,这将要求派生类实现公共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();
}
Run Code Online (Sandbox Code Playgroud)
我给它一个基类本身的返回类型; 每个实现必须返回一个遵循DBEntityBase的值,当然,所有派生类都会这样做.由于Clone()方法返回一个派生类本身的类型,然后...似乎有意义,这将工作.
DeliverableEntity originalEntity = new DeliverableEntity();
DeliverableEntity clonedEntity = originalEntity.Clone();
Run Code Online (Sandbox Code Playgroud)
但是,在构建时,我收到错误..
'DeliverableEntity'没有实现继承的抽象成员'DBEntityBase.Clone()'
大概是由于返回类型.
我知道我可能只是将Clone()方法放在一个单独的实用程序类中,而不是直接在每个实体模型中实现它......这会让我解决我的问题(并且可能会节省大量的实现代码),但我是仍然想知道为什么这不起作用.似乎应该有办法做到这一点.
UPDATE
为了回应@Luann的第一个回复(谢谢),我将更改改为"覆盖"......
public partial class DeliverableEntity
{
public override DeliverableEntity Clone()
{
return this.Clone<DeliverableEntity>();
}
}
Run Code Online (Sandbox Code Playgroud)
我现在收到以下错误...
返回类型必须是'DBEntityBase'才能匹配被覆盖的成员'DBEntityBase.Clone()'
解
感谢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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
有些事要注意......
现在很酷的部分是所有实体都可以访问该功能......
// 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();
Run Code Online (Sandbox Code Playgroud)
我喜欢这个解决方案,因为它具有基类的简单性,其中实现在一个位置定义(而我正在考虑在每个派生类中单独实现一个抽象方法),因为它与DBEntityBase类相关联,并且在同一个位置命名空间,它成为基类定义的"契约"的一部分,这意味着只要我有一个派生自DBEntityBase的类,我就可以指望它可用.
按流行要求..
尝试扩展方法:
public T Clone<T>(this T obj) where T : DBEntityBase
{
return /* insert code that creates clone here */
}
Run Code Online (Sandbox Code Playgroud)
我必须诚实,我不认为这会起作用,因为我预计C#将无法准确确定它的扩展名.但显然它确实如此!