需要帮助来理解这个 C# 泛型类
我正在学习 Nhibernate 3.0。在示例代码示例之一中,它创建了一个抽象基实体类:
public abstract class Entity<T> where T : Entity<T>
然后,使 Customer
实体继承自 Entity
基类:
public class Customer : Entity<Customer>
我知道它是一个抽象泛型类,并且它使用 where
关键字来确保类型 T
是 Entity
,这就是我感到困惑的地方。
Customer
继承自“Entity
”,此“Entity
”将“Customer
”作为T
,但此Customer
不是“Entity
”。
请帮助我理解这一点,我真的对这个通用类感到困惑。
I am learning Nhibernate 3.0. In one of the sample code examples, it creates an abstract base entity class:
public abstract class Entity<T> where T : Entity<T>
then, make the Customer
entity inherit from the Entity
base class:
public class Customer : Entity<Customer>
I understand it's an abstract generic class, and it is using the where
keyword to make sure the type T
is Entity<T>
, this is where I get confused.
Customer
inherits from "Entity<Customer>
", this "Entity<Customer>
" takes "Customer
" as T
, but this Customer
is not "Entity<T>
".
Please help me to understand this, I'm really confused by this generic class.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你说这没有任何意义,因为这就是继承的含义。它建立了一种“是”关系。所以实际上Customer
是一个Entity
抱歉,这是基于删除了泛型的代码,因为它不在代码块中。
但同样的原则仍然有效。这有点令人困惑,因为它看起来像是一个递归定义,但事实并非如此。
将其视为的其余部分是什么样子,但我想它有一些方法使用它自己的类型作为通用参数。
Customer
继承自Entity
恰好有一些方法或字段依赖于通用参数本身,例如Customer
。我不熟悉 NHibernate,所以我不知道 Entity举例来说,它有一个名为的方法
,该方法返回它自己的实例的列表。它需要该方法返回具体类型而不是基本类型。因此,在
Customer
类中,该方法将是如果它没有通用参数,它只能返回
IEnumerable
这只是一个示例可以使用,不知道实际使用起来如何。
You saidThat doesn't make any sense because that's what inheritance means. It establishes an "is a" relationship. So in fact aCustomer
is anEntity
Sorry that was based on the code with the generics stripped out because it wasn't in a code block.
The same principle is still valid though. It's just a little confusing because it looks like it's a recursive definition, but it's not.
Think of it as
Customer
inherits fromEntity
There just happens to be methods or fields that depend on the generic parameter being itself e.g.Customer
. I'm not familiar with NHibernate so I don't know what the rest ofEntity<T>
looks like, but I imagine it has some methods that use it's own type as a generic parameter.Say for instance it has a method called
that returned a list of it's own instances. It needs that method to return the concrete type rather than the base type. So in the
Customer
class, that method would beIf it didn't have the generic parameter, it could only return
IEnumerable<Entity>
That's just an example of how it could be used, I don't know how it's actually used.
当您考虑基“Entity”类尝试执行哪些操作时,它会更有意义。我也不熟悉 nhibernate,但我想其中一种方法可能类似于 Save() 方法。因此,您创建的从 Entity 类继承的任何类都将继承 Save() 方法,这样您就不必为创建的每个业务对象重写它。但是,基实体类必须知道您要保存的对象类型。它可以使用反射,但这里它使用泛型来允许您告诉它继承 Entity 的类是什么类型。
问题是,当 20 个不同的类继承自一个基类时,该基类实际上并不知道谁在使用其功能。这是一种让基类知道“客户”正在使用其方法的方法,以便它可以专门满足“客户”的需求。
It will make more sense when you consider what operations the base 'Entity' class tries to perform. I'm also not familiar with nhibernate, but I would imagine one of the methods might be something akin to a Save() method. So any class you create that inherits from the Entity class would inherit a Save() method, keeping you from having to rewrite it for every business object you make. However, the Base entity class has to know what type of object you are trying to save. It could use reflection, but here it uses generics to allow you to tell it what kind of class it is that is inheriting Entity.
The thing is that when 20 different classes inherit from a base class, that base class doesn't really have any knowledge of who is using its functionality. This is a way to let the base class know "Customer" is using its methods so that it can cater specifically to "Customer"'s needs.
where
子句指定要T
被替换的类型必须遵守的条件。因此,如果类型为Customer
(如第二行代码中的Entity
所示),则条件为Customer : Entity
code> ... 即Customer
必须是Entity
的子类,否则会出现编译错误。事实上,在第二行代码中也是如此声明的。将其应用到您所写的内容中:
下面是我的说法:
Entity
是Entity< 的实例化/code> 用
Customer
替换T
。T
只是某种类型的占位符;它是一个类型参数。我们也可以用 SomeType 而不是
T
来编写抽象方法声明。条件是,为了实例化Entity<
SomeType>
,SomeType 必须是 <代码>Entity<SomeType>
。将Customer
替换为 SomeType,这表示Customer
必须是Entity
的子类,并且它是。如果您了解
T
只是一个参数,并且在Entity的情况下用
Customer
代替它< /code>,那么我不明白为什么你说“这个客户不是“Entity
””,因为Customer : Entity
声明了它到就是这样(在Entity
定义中每次出现时用Customer
替换T
)。The
where
clause specifies a condition that the type to be substituted forT
must obey. So, if the type isCustomer
, as inEntity<Customer>
in that second line of code, then the condition isCustomer : Entity<Customer>
... i.e.,Customer
must be a subclass ofEntity<Customer>
, else there's a compile error. And indeed it is so declared, again in that second line of code.Applying this to what you wrote:
Here's how I would put it:
Entity<Customer>
is an instantiation ofEntity<T>
withCustomer
substituted forT
.T
is just a placeholder for some type; it's a type parameter.We could just as well write the abstract method declaration with SomeType instead of
T
. The condition is that, in order to instantiateEntity<
SomeType>
, SomeType must be a subclass ofEntity<
SomeType>
. SubstitutingCustomer
for SomeType, that says thatCustomer
must be a subclass ofEntity<Customer>
, and it is.If you understand that
T
is just a parameter, and thatCustomer
is substituted for it in the case ofEntity<Customer>
, then I don't understand why you say that 'this customer is not "Entity<T>
"', sinceCustomer : Entity<Customer>
declares it to be just that (withCustomer
substituted forT
in every occurrence in the definition ofEntity<T>
).显示如何使用此类继承的示例:
Sample showing how one can use such inheritance: