C#继承与泛型类似乎创建不同的对象类型
我有一个抽象类,我用于实体框架。然后,我会继承该类并在需要时重写。在这种情况下,我有一个帖子,我想删除,并与我想删除与帖子相关的评论。逻辑很简单,但我似乎越来越奇怪类类型的问题。C#继承与泛型类似乎创建不同的对象类型
这是我所期望的工作。但是,entity.ID
不存在。实际上,实体对象根本没有任何属性(就Visual Studio intellisense而言)。我试图施放它,它说它不能将Post传递给MyProject.Models.Post,尽管它应该是完全相同的类。因此,似乎通过使用泛型类型并在继承期间将其转换,它正在创建一个具有相同名称的新类。
public abstract class MyAbstractService<T>
{
public virtual void Delete<T>(T entity)
{
this.context.Set<T>().Remove(entity);
}
}
public abstract class MyAbstractService :AbstractService<Post>
{
public override void Delete<Post>(Post entity)
{
this.context.PostComments.RemoveRange(this.context.PostComments.Where(x => x.Post.ID == entity.ID));
base.Delete(entity);
}
}
我能够通过使用下面的方法来解决这个类型的问题,但我不明白为什么这发生在第一个地方。我假设有一个更好的方法来处理这个比我在这里使用的铸造方法。如果没有其他选择,首先要做的是什么?
public override void Delete<Post>(Post entity)
{
MyProject.Models.Post pst = entity as MyProject.Models.Post;
this.context.PostComments.RemoveRange(this.context.PostComments.Where(x => x.Post.ID == pst.ID));
base.Delete(entity);
}
基于评论它似乎像这将是实现删除的更优选的方式,但是我还是觉得抽象的方法是使用的,因为我一直在使用它的许多其他实体没有关系。
public void Delete(Post entity)
{
this.context.PostComments.RemoveRange(this.context.PostComments.Where(x => x.Post.ID == entity.ID));
base.Delete(entity);
}
你Delete
上MyAbstractService
方法是定义,指出任何MyAbstractService
能够删除的任何类型任何对象的方法。
因此,当您从该抽象类继承并提供该方法的实现时,您需要提供一种能够删除任何类型的任何对象的方法。您已在实现中将您的通用类型Post
命名(您可以随意调用它),但调用该通用参数Post
并不意味着该实例的类型为Post
,这只是泛型类型的名称,所以对象可以是任何类型的。如果你想对待对象,就好像它是Post
类型的那样,你需要将它施放,就像你在做什么一样。
现在你有这就是签名索赔它可以接受的对象的任何类型的方法,但在现实中,如果不是Post
类型的对象,它只会失败。这是糟糕的设计;你的API对其呼叫者撒谎。
相反,MyAbstractService
类型有一种方法可以删除任何类型的对象。 Delete
不应该是通用的开始。相反,它应该只使用类的泛型,而不是定义第二个泛型类型(您也称为T
,足够容易混淆)。
感谢您的答案。第一部分是有道理的,但最后一段我有点困惑。 VS确实给出了2个参数命名相同的警告,但是如果我试图改变它,我会得到错误。如果我完全删除泛型类型,我得到一个错误this.context.Set
@DanHastings如果'Set'说你需要使用一个引用类型的类型然后*确保你传递的类型是一个引用类型*。创建你不想要的其他类型只会导致你的问题。同样,你不希望你的'Delete'方法能够接受任何类型的任何对象。你不打算提供这种行为,所以不要定义声称提供它的方法。 – Servy
我已经用删除方法的更新示例更新了问题。我明白你的意思是我需要为特定的删除实现自定义功能。更新的方法起作用。但是,我使用抽象类中的删除方法来删除许多其他没有关系的实体,例如删除评论。如果我的抽象方法仍然错误,我应该怎么做才能纠正它?我希望它能够删除任何类型的实体,这就是它现在正在做的事情 –
为什么你要为Delete方法声明一个泛型类型参数'T'?不是泛型类型参数(也称为'T')指定的类型方法的参数吗? (编辑:见下面的答案...) – elgonzo
它似乎不喜欢当我在方法调用的类型括号中使用完整的命名空间。即删除,它不让我把它放在方法param的前面,因为它使它与泛型被指定为 –
@DanHastings的不同类型。实际上,你不能命名你定义的MyProject的泛型类型。 Models.Post'。这不是您定义的新类型的有效标识符。它也不允许你将该类型作为你的方法的参数,因为你正在覆盖的抽象类声明方法参数是泛型类型,而不是'MyProject.Models.Post'。 – Servy