generics与inheritance(当不涉及集合类时)

这是这个问题的延伸,可能甚至可能是其他一些问题的重复(如果是这样,请原谅我)。 我在MSDN上看到generics通常与集合一起使用

generics类的最常见用途是使用链接列表,散列表,堆栈,队列,树等集合,其中诸如添加和删除集合中的项的操作以大致相同的方式执行,而不管数据类型是什么存储。

我看到的例子也validation了上述陈述。

有人可以在不涉及任何集合的现实场景中有效地使用generics吗?

小心翼翼地,我正在考虑制作一个不涉及collections的例子

public class Animal { public void Speak() { Console.WriteLine("I am an Animal and my type is " + typeof(T).ToString()); } public void Eat() { //Eat food } } public class Dog { public void WhoAmI() { Console.WriteLine(this.GetType().ToString()); } } 

和“狗的动物”将是

Animal magic = new Animal();

完全有可能让DogAnimalinheritance(假设Animal的非通用版本) Dog:Animal因此Dog Animal

我想的另一个例子是BankAccount 。 它可以是BankAccountBankAccount 。 这很可能是Checking:BankAccountSavings:BankAccount

是否有任何最佳实践来确定我们是否应该使用generics或inheritance?

你可能会得到一些更好的答案,但同时要考虑这一点:generics类意味着generics类和参数类之间的“关系”。

所有的狗都是动物,因此它们与所有其他动物共享某些属性/品质。 如果使用inheritance,则很容易在Animal类中实现这些常用品质,并在后代类中添加品质。 但如果你使用Animal (Of Dog)实现它,那么:

  1. 你的Dog类本身并不是一个完全合格的狗/动物,因为它的“动物特性”包含在Animal (Of T)类中。 狗必须在亲子关系中与动物绑在一起。
  2. 你的Animal类不是真正的动物:你不能创建一些接受动物作为参数的方法,因为你不能引用全球化的Animal (Of T)类。 它实际上是一个具有共同行为的类系列,而不是超类。 你失去了在Animal (Of T)课外处理动物的好处。

但是,恕我直言,你应该如何看待generics:想想一个MedicalDoctor(Of T)类。 Veterinarian(Of T as Animal)将inheritance自MedicalDoctor(Of Animal)DogVeterinarian将inheritanceVeterinarian(Of Dog)

关键点:generics类和参数类没有紧密耦合和共同依赖,它们共存。

顺便说一句,如果你想看到一些非常好的非收集使用generics,请注意我们的代表:Action(Of T),Func(Of Traesult),Comparison(Of T),EventHandler(Of TEventArgs),Converter(Of TSource,TResult)……和接口:IEqualityComparer(Of T),IComparer(Of T)……

知道的一个真实世界的例子是在WCF Channel Factory中 。

从页面:

 public sealed class Test { static void Main() { // Code not shown. } public void Run() { // This code is written by an application developer. // Create a channel factory. BasicHttpBinding myBinding = new BasicHttpBinding(); EndpointAddress myEndpoint = new EndpointAddress("http://localhost/MathService/Ep1"); ChannelFactory myChannelFactory = new ChannelFactory(myBinding, myEndpoint); // Create a channel. IMath wcfClient1 = myChannelFactory.CreateChannel(); double s = wcfClient1.Add(3, 39); Console.WriteLine(s.ToString()); ((IClientChannel)wcfClient1).Close(); // Create another channel. IMath wcfClient2 = myChannelFactory.CreateChannel(); s = wcfClient2.Add(15, 27); Console.WriteLine(s.ToString()); ((IClientChannel)wcfClient2).Close(); myChannelFactory.Close(); } } 

我认为generics的方式是它们代表一个类正在作用的类型。 例如,ChannelFactory构建类型为T的工厂。inheritance表示类型之间的层级关系。 狗是动物,金毛是狗和动物。

Nullable是通用的,不是集合类,并且涉及inheritance,因为它与struct

generics委托系列非常好 – EventHandlerAction<...]>Func<[...]> – 更清楚的是Func而不是某些自定义IdPredicate或其他什么。

你将inheritance的“is-a”方面与generics的“of”方面混为一谈。

generics意味着跨类操作的相同性,而不仅仅是操作存在多态。

在您的Animal示例中, Animal的实例没有WhoAmI方法,而Dog : Animal的实例会。

请在你的情况下使用inheritance。
如果一个类可以被另一个类正确描述[例如,一个正方形可以描述为一个矩形],则该正方形应该从矩形任务inheritance/扩展。 否则,你就陷入了混乱。

使用GenericClass来表示this is a GenericClass object of tType-s使用Square:Rectangle意味着this is a Square, which is also a Rectangle

在你的情况下:
使用Dog:Animal意味着this is a Dog, which is also an Animal