Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有泛型类型的C#继承似乎正在创建不同的对象类型_C#_Generics_Inheritance - Fatal编程技术网

带有泛型类型的C#继承似乎正在创建不同的对象类型

带有泛型类型的C#继承似乎正在创建不同的对象类型,c#,generics,inheritance,C#,Generics,Inheritance,我有一个抽象类,用于实体框架。然后我继承该类并在需要时重写。在这种情况下,我有一篇文章要删除,我想删除与该文章相关的评论。逻辑很简单,但我似乎遇到了奇怪的类类型问题 这就是我所期望的效果。但是,entity.ID不存在。事实上 实体对象根本没有属性(就visual studio intellisense而言)。我试着将它转换为一个类,它说它不能将Post转换为MyProject.Models.Post,即使它应该是完全相同的类。因此,通过使用泛型类型并在继承过程中强制转换它,它似乎正在生成一个同

我有一个抽象类,用于实体框架。然后我继承该类并在需要时重写。在这种情况下,我有一篇文章要删除,我想删除与该文章相关的评论。逻辑很简单,但我似乎遇到了奇怪的类类型问题

这就是我所期望的效果。但是,
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);
    }
}

您的
MyAbstractService
上的
Delete
方法正在定义一个方法,该方法表示任何
MyAbstractService
都可以删除任何类型的对象

因此,当您从该抽象类继承并提供该方法的实现时,您需要提供能够删除任何类型的任何对象的方法。您已经在实现中将泛型类型命名为
Post
(您可以随意调用它),但是调用泛型参数
Post
并不意味着实例的类型为
Post
,这只是泛型类型的名称,因此对象可以是任何类型。如果要将对象视为类型为
Post
的对象,则需要在执行时强制转换它

现在您有了一个方法,它的签名声明它可以接受任何类型的对象,但实际上,如果它不是
Post
类型的对象,它就会失败。这是糟糕的设计;您的API对调用方撒谎


相反,
MyAbstractService
类型拥有一个可以删除任何类型对象的方法是没有意义的<代码>删除一开始不应该是通用的。相反,它应该只使用类的泛型类型,而不是定义第二个泛型类型(您也将其称为
T
,这很容易混淆)。

您在
MyAbstractService
上的
Delete
方法定义了一个表示任何
MyAbstractService
都可以删除任何类型的对象的方法

因此,当您从该抽象类继承并提供该方法的实现时,您需要提供能够删除任何类型的任何对象的方法。您已经在实现中将泛型类型命名为
Post
(您可以随意调用它),但是调用泛型参数
Post
并不意味着实例的类型为
Post
,这只是泛型类型的名称,因此对象可以是任何类型。如果要将对象视为类型为
Post
的对象,则需要在执行时强制转换它

现在您有了一个方法,它的签名声明它可以接受任何类型的对象,但实际上,如果它不是
Post
类型的对象,它就会失败。这是糟糕的设计;您的API对调用方撒谎


相反,
MyAbstractService
类型拥有一个可以删除任何类型对象的方法是没有意义的<代码>删除一开始不应该是通用的。相反,它应该只使用类的泛型类型,而不是定义第二个泛型类型(您也将其称为
T
,这已经足够令人困惑了)。

为什么要为Delete方法声明泛型类型参数
T
?类泛型类型参数(也称为
t
)指定的类型的方法的参数不是吗?(编辑:请参见下面的答案…)我似乎不喜欢在方法调用的类型括号中使用完整的命名空间。i、 e.Delete,它不允许我将它放在方法param前面,因为它使它成为与泛型指定的类型不同的类型as@DanHastings实际上,您不能命名您正在定义的泛型类型
MyProject.Models.Post
。这不是您正在定义的新类型的有效标识符。它也不允许您将该类型作为方法的参数,因为您要覆盖的抽象类声明该方法参数是泛型类型,而不是
MyProject.Models.Post
。为什么要为Delete方法声明泛型类型参数
t
?类泛型类型参数(也称为
t
)指定的类型的方法的参数不是吗?(编辑:请参见下面的答案…)我似乎不喜欢在方法调用的类型括号中使用完整的命名空间。i、 e.Delete,它不允许我将它放在方法param前面,因为它使它成为与泛型指定的类型不同的类型as@DanHastings实际上,您不能命名您正在定义的泛型类型
MyProject.Models.Post
。这不是您正在定义的新类型的有效标识符。它也不允许您将该类型作为方法的参数,因为您要覆盖的抽象类声明该方法参数是泛型类型,而不是
MyProject.Models.Post
。谢谢您的回答。第一部分有道理,但最后一段让我有点困惑。VS确实会发出警告,指出这两个参数的名称相同,但如果我试图更改它,就会出现错误。如果我完全删除泛型类型,我会在this.context.Set中得到一个错误,即T必须是引用类型。如果我更改它以便使用Delete(T entity),它表示它无法将T转换为Y。当两者都命名为T时,它可以工作。在所有情况下,这个方法都是有效的,我需要使它具有依赖性custom@DanHastings如果
Set
表示需要使用引用类型的类型,请确保传递的类型是引用类型。创建不需要的其他类型只会给您带来问题。再说一次,你知道
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);
}