简体   繁体   English

任何人都可以举一个很好的例子来说明如何使用泛型类?

[英]Can anybody give a good example of what to use generic classes for?

We recently learned about generic classes in C#, but our teacher failed to mention what they can be used for. 我们最近了解了C#中的泛型类,但我们的老师没有提到它们可以用于什么。 I can't really find any good examples and would be extremly happy if somebody help me out :) 我真的找不到任何好的例子,如果有人帮助我,我会非常高兴:)

Have you made your own generic class, and what did you use it for? 你有自己的通用课程吗?你用它做了什么?

Some code examples would make me, and my classmates, really happy! 一些代码示例会让我和我的同学们真的很开心! Pardon the bad english, I am from sweden :) 请原谅,英语不好,我来自瑞典:)

happy programming! 快乐的编程!

Sorry- I think I could have written the question a bit better. 对不起 - 我想我可以把问题写得好一点。 I am familar with generic collections. 我熟悉通用集合。 I just wondered what your own generic classes can be used for. 我只是想知道你自己的泛型类可以用于什么。

and thank you for the MSDN links, I did read them before posting the question, but maybe I missed something? 并且感谢您的MSDN链接,我在发布问题之前就已经阅读了它们,但也许我错过了什么? I will have a second look! 我会再看看!

Generic Collections 通用集合

Generics for collections are very useful because they allow compile time type safety. 集合的泛型非常有用,因为它们允许编译时类型安全。 This is useful for a few reasons: 这有用的原因有以下几点:

  • No casting is required when retreiving values. 在检索值时不需要铸造。 This is not only a performance benefit but also eliminates the risk of there being a casting exception at runtime 这不仅具有性能优势,还消除了运行时出现转换异常的风险

  • When value types are added to a non generic list such as an ArrayList, the value's have to be boxed. 将值类型添加到非泛型列表(如ArrayList)时,必须将值设置为框。 This means that they are stored as reference types. 这意味着它们存储为引用类型。 It also means that not only does the value get stored in memory, but so does a reference to it, so more memory than necessery is used. 这也意味着不仅值被存储在内存中,而且对它的引用也是如此,因此使用了比necessery更多的内存。 This problem is eliminated when using generic lists. 使用通用列表时,可以消除此问题。

Generic Classes 通用类

Generic classes can be useful for reusing common code for different types. 通用类可用于重用不同类型的公共代码。 Take for example a simple non generic factory class: 以一个简单的非通用工厂类为例:

public class CatFactory
{
  public Cat CreateCat()
  {
    return new Cat();
  }
}

I can use a generic class to provide a factory for (almost) any type: 我可以使用泛型类为(几乎)任何类型提供工厂:

public class Factory<T> where T : new()
{
  public T Create()
  {
    return new T();
  }
}

In this example I have placed a generic type constraint of new() on the type paramter T. This requires the generic type to contain a parameterless contructor which enables me to create an instance without knowing the type. 在这个例子中,我在类型参数T上放置了new()的泛型类型约束。这要求泛型类型包含一个无参数的构造函数,这使我能够在不知道类型的情况下创建实例。

Just because you said you are Swedish, I thought I'd give an example integrating IKEA furniture. 只是因为你说你是瑞典人,我想我会举一个整合宜家家具的例子。 Your kit couches are an infestation in north america, so I thought I'd give something back :) Imagine a class which represents a particular kit for building chairs and tables. 你的套装沙发是北美的一种感染,所以我想我会回馈一些东西:)想象一个代表一个特殊的椅子和桌子套件的课程。 To remain authentic, I'll even use nonsense swedish linguistic homonyms: 为了保持真实,我甚至会使用无意义的瑞典语言同音异义词:

// interface for included tools to build your furniture
public interface IToolKit {
    string[] GetTools();
}

// interface for included parts for your furniture    
public interface IParts {
    string[] GetParts();
}

// represents a generic base class for IKEA furniture kit
public abstract class IkeaKit<TContents> where TContents : IToolKit, IParts, new() {
    public abstract string Title {
        get;
    }

    public abstract string Colour {
        get;
    }

    public void GetInventory() {
        // generic constraint new() lets me do this
        var contents = new TContents();
        foreach (string tool in contents.GetTools()) {
            Console.WriteLine("Tool: {0}", tool);
        }
        foreach (string part in contents.GetParts()) {
            Console.WriteLine("Part: {0}", part);
        }
    }
}

// describes a chair
public class Chair : IToolKit, IParts {
    public string[] GetTools() {
        return new string[] { "Screwdriver", "Allen Key" };
    }

    public string[] GetParts() {
        return new string[] {
            "leg", "leg", "leg", "seat", "back", "bag of screws" };
    }
}

// describes a chair kit call "Fnood" which is cyan in colour.
public class Fnood : IkeaKit<Chair> {
    public override string Title {
        get { return "Fnood"; }
    }

    public override string Colour {
        get { return "Cyan"; }
    }
}

public class Snoolma : IkeaKit<Chair> {
    public override string Title {
        get { return "Snoolma "; }
    }

    public override string Colour {
        get { return "Orange"; }
    }
}

Ok, so now we've got all the bits we need to figure out how to build some cheap furniture: 好的,现在我们已经掌握了如何构建一些廉价家具所需的所有东西:

var fnood = new Fnood();
fnood.GetInventory(); // print out tools and components for a fnood chair!

(Yes, the lack of instructions and the three legs in the chair kit is deliberate.) (是的,缺乏说明和椅子套件中的三条腿是故意的。)

Hope this helps in a cheeky way. 希望这有助于以一种厚颜无耻的方式。

If one has a List object (non-generic), one can store into it anything that can be cast into Object, but there's no way of knowing at compile time what type of things one will get out of it. 如果有一个List对象(非泛型),可以将任何可以转换为Object的东西存储到其中,但是在编译时无法知道将从中获取什么类型的东西。 By contrast, if one has a generic List<Animal>, the only things one can store into it are Animal or derivatives thereof, and the compiler can know that the only things that will be pulled out of it will be Animal. 相比之下,如果一个人拥有一个通用的List <Animal>,那么人们可以存储的唯一内容就是Animal或其衍生物,并且编译器可以知道将从中提取的唯一内容将是Animal。 The compiler can thus allow things to be pulled out of the List and stored directly into fields of type Animal without any need for run-time type checking. 因此,编译器可以将事物从List中拉出并直接存储到Animal类型的字段中,而无需进行运行时类型检查。

Additionally, if the generic type parameter of a generic class happens to be a value type, use of generic types can eliminate the need for casting to and from Object, a process called "Boxing" which converts value-type entities into reference-type objects; 此外,如果泛型类的泛型类型参数恰好是值类型,则使用泛型类型可以消除对与Object进行强制转换的需要,这是一个名为“Boxing”的过程,它将值类型实体转换为引用类型对象; boxing is somewhat slow, and can sometimes alter the semantics of value-type objects, and is thus best avoided when possible. 拳击有点慢,有时可以改变值类型对象的语义,因此最好尽可能避免。

Note that even though an object of type SomeDerivedClass may be substitutable for TheBaseClass, in general, a GenericSomething<SomeDerivedClass> is not substitutable for a GenericSomething<TheBaseClass>. 请注意,即使SomeDerivedClass类型的对象可能可替代TheBaseClass,通常,GenericSomething <SomeDerivedClass>也不能替代GenericSomething <TheBaseClass>。 The problem is that if one could substitute eg a List<Giraffe> for a List<Zebra>, one could pass a List<Zebra> to a routine that was expecting to take a List<Giraffe> and store an Elephant in it. 问题是,如果可以替换List <Giraffe>作为List <Zebra>,可以将List <Zebra>传递给期望采用List <Giraffe>并将Elephant存储在其中的例程。 There are a couple of cases where substitutability is permitted, though: 但有几种情况允许可替代性,但:

  1. Arrays of a derived type may be passed to routines expecting arrays of base type, provided that those routines don't try to store into those arrays any items that are not of the proper derived type. 派生类型的数组可以传递给期望基类型数组的例程,前提是这些例程不会尝试将任何不属于正确派生类型的项存储到这些数组中。
  2. Interfaces may be declared to have "out" type parameters, if the only thing those interfaces will do is return ("output") values of that type. 接口可以声明为具有“out”类型参数,如果这些接口唯一要做的就是返回(“输出”)该类型的值。 A Giraffe-supplier may be substituted for an Animal-supplier, because all it's going to do is supply Giraffes, which are in turn substitutable for animals. 长颈鹿供应商可能会取代动物供应商,因为它所要做的就是供应长颈鹿,长颈鹿又可以替代动物。 Such interfaces are "covariant" with respect to those parameters. 这些接口相对于那些参数是“协变的”。

In addition, it's possible to declare interfaces to declare "in" type parameters, if the only thing the interfaces do is accept parameters of that type by value. 此外,如果接口所做的唯一事情是按值接受该类型的参数,则可以声明接口以声明“in”类型参数。 An Animal-eater may be substituted a Giraffe-eater, because--being capable of eating all Animals, it is consequently capable of eating all Giraffes. 动物食者可能会取代长颈鹿食者,因为 - 能够食用所有动物,因此能够吃掉所有长颈鹿。 Such interfaces are "contravariant" with respect to those parameters. 这些接口相对于那些参数是“逆变的”。

The most common example is for collections such as List, Dictionary, etc. All those standard classes are implemented using generics. 最常见的例子是List,Dictionary等集合。所有这些标准类都是使用泛型实现的。

Another use is to write more general utility classes or methods for operations such as sorting and comparisons. 另一个用途是为诸如排序和比较之类的操作编写更通用的实用程序类或方法。

real world example for generics. 仿制药的现实世界的例子。

Think u have a cage where there are many different birds(parrot,pegion,sparrow,crow,duck) in it(non generic). 你认为你有一个笼子里面有许多不同的鸟类(鹦鹉,pegion,麻雀,乌鸦,鸭子)(非通用)。

Now you are assigned a work to move the bird to seperate cages(specifically built for single bird) from the cage specified above. 现在,您被分配了一项工作,将鸟类从上面指定的笼子移动到单独的笼子(专门为单鸟建造)。

(problem with the non generic list) It is a tedious task to catch the specific bird from the old cage and to shift it to the cage made for it.(Which Type of bird to which cage --Type casting in c#) (非通用列表的问题)从旧笼子中捕捉特定的鸟并将其移动到为其制作的笼子中是一项繁琐的任务。(笼子里的哪种鸟类 - c#中的类型铸造)

generic list 通用名单

Now think you have a seperate cage for seperate bird and you want to shift to other cages made for it. 现在想想你有一个单独的笼子隔离鸟,你想转移到其他笼子。 This will be a easy task and it wont take time for you to do it(No type casting required-- I mean mapping the birds with cages). 这将是一项简单的任务,你不需要花时间去做(不需要任何类型的铸造 - 我的意思是用笼子绘制鸟类)。

Well, you have a lot of samples inside the framework. 好吧,你在框架内有很多样本。 Imagine that you need to implement a list of intergers, and later a list of strings... and later a list of you customer class... etc. It would be very painfull. 想象一下,你需要实现一个整数列表,然后是一个字符串列表......以及稍后你的客户类列表...等等。这将是非常痛苦的。

But, if you implements a generic list the problem is solved in less time, in less code and you only have to test one class. 但是,如果您实现了一个通用列表,问题可以在更短的时间内解决,代码更少,您只需要测试一个类。

Maybe one day you will need to implement your own queue, with rules about the priority of every element. 也许有一天你需要实现自己的队列,并有关于每个元素的优先级的规则。 Then, it would be a good idea to make this queue generic if it is possible. 然后,如果可能的话,将此队列设为通用是个好主意。

This is a very easy sample, but as you improve your coding skills, you will see how usefull can be to have (for example) a generic repository (It's a design patters). 这是一个非常简单的示例,但随着您提高编码技能,您将看到(例如)通用存储库(它是设计模式)的有用性。

Not everyday programmers make generic classes, but trust me, you will be happy to count with such tool when you need it. 不是每天的程序员都会编写泛型类,但相信我,你会很乐意在需要的时候使用这样的工具。

Here is a Microsoft article that can be of help: http://msdn.microsoft.com/en-us/library/b5bx6xee%28v=vs.80%29.aspx 这是一篇可以提供帮助的Microsoft文章: http//msdn.microsoft.com/en-us/library/b5bx6xee%28v=vs.80%29.aspx

The largest benefit that I've seen is the compile-time safety of generics, as @Charlie mentioned. 正如@Charlie所提到的,我看到的最大的好处是泛型的编译时安全性。 I've also used a generic class to implement a DataReader for bulk inserts into a database. 我还使用了一个泛型类来实现DataReader,以便批量插入到数据库中。

My friend is not a programmer and I would like to explain what is generics? 我的朋友不是程序员,我想解释一下什么是泛型? I would explain him generics as below. 我会在下面解释他的泛型。 Thus this is a real-world scenario of using generics. 因此,这是使用泛型的真实场景。

"There is this manufacturer in the next street. He can manufacture any automobile. But at one instance he can manufacture only one type of automobile. Last week, he manufactured a CAR for me, This week he manufactured a TRUCK for my uncle. Like I said this manufacturing unit is so generic that it can manufacture what the customer specifies. But note that when you go to approach this manufacturer, you must go with a type of automobile you need. Otherwise approaching him is simply not possible." “在下一条街上有这家制造商。他可以制造任何汽车。但有一次,他只生产一种汽车。上周,他为我制造了一辆汽车,本周他为我的叔叔制造了一辆卡车。我说这个制造单位是如此通用,它可以制造客户指定的东西。但请注意,当你去接近这个制造商时,你必须使用你需要的一种汽车。否则接近他是根本不可能的。“

Have a look at this article by Microsoft. 看看微软的这篇文章。 You have a nice and clear explanation of what to use them for and when to use them. 您可以清楚地了解如何使用它们以及何时使用它们。 http://msdn.microsoft.com/en-us/library/ms172192.aspx http://msdn.microsoft.com/en-us/library/ms172192.aspx

The various generic collections are the best example of generics usage but if you want an example you might generate yourself you could take a look at my anwer to this old question: 各种通用集合是泛型使用的最佳示例,但如果您想要一个自己可以生成的示例,您可以查看我对这个旧问题的回答:

uses of delegates in c or other languages 使用c或其他语言的代表

Not sure if it's a particularly great example of generics usage but it's something I find myself doing on occasion. 不确定它是否是仿制药使用的一个特别好的例子,但这是我偶尔会发现的事情。

Are you talking about a base class (or perhaps an abstract class)? 你在谈论一个基类(或者一个抽象类)? As a class that you would build other classes (subclasses) off of? 作为一个类,您将构建其他类(子类)?

If that's the case, then you'd create a base class to include methods and properties that will be common to the classes that inherit it. 如果是这种情况,那么您将创建一个基类来包含对继承它的类通用的方法和属性。 For example, a car class would include wheels, engine, doors, etc. Then maybe you'd maybe create a sportsCar subclass that inherits the car class and adds properties such as spoiler, turboCharger, etc. 例如,汽车类将包括车轮,发动机,车门等。那么也许你可能会创建一个继承汽车类的sportsCar子类并添加诸如扰流板,turboCharger等属性。

http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming ) enter link description here http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming在此处输入链接说明

It's hard to understand what you mean by "generic class" without some context. 如果没有某些背景,很难理解“泛类”的含义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 谁能举一个动态增长链式哈希表的通用类型的例子吗? - Can anyone give an example of a generic type for dynamically growing chained hashtables? 这是使用抽象类的一个好例子吗? - Is this a good example of using abstract classes? 这是一个很好地使用继承的例子吗? - Is this an example of a good use of inheritence? 当我不知道什么是T时,如何在另一种方法中使用泛型类? - How Can I use generic classes in another method when I dont know what is T? 可以举个例子,说明何时应该使用UIElement.UpdateLayout()? - Can give me an example that when should use UIElement.UpdateLayout()? 我们可以在不使用EF的情况下使用通用存储库吗? 这是一个好习惯吗? - Can we use Generic Repository without using EF? Is it a good practise? 在通用类的层次结构中使用访问者模式的最佳方法是什么? - What is the best way to use visitor pattern in a hierarchy of generic classes? 为什么我们不能使用密封类作为通用约束? - Why we can’t use sealed classes as generic constraints? 您可以在 ASP Net Core 控制器中使用通用基类吗? - Can you use generic base classes in ASP Net Core Controllers? TLSharp - 有人有例子吗? - TLSharp - anybody have example?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM