Why and where are generics actually used?

I know that generic tools are used to provide type safety, and I often read that they are mostly used in user collections. But why do we even need to have them in common?

For example,

Why can't I use string[] instead of List<string> ?

Let's consider that I declare a generic class and it has a generic parameter type X.

 T x; 

If I provide a class method that does

 x = x + 1; 

What does this really mean? I don't know what T actually will be, and I don't know what x = x + 1 will actually perform.

If I cannot do my own manipulations in my methods, how will generators help me anyway?

I have already learned a lot of book answers. It would be very grateful if someone could give some clear ideas on this.

Regards, NLV

+7
generics c #
source share
10 answers

Your question is answered by yourself. Array types themselves are a form of typical typing. If we installed a general type system in CLR v1.0, I would bet that there would be no special type of array, just Array<T> along with List<T> , etc. Since the first version of the CLR did not have common types, we introduce the most important and obvious general type into it - the type of the array. And, as a result, there is a whole bunch of special code for processing arrays; one common CLR type is supported in version 1.0.

Since arrays are essentially a generic type, your question answers itself: the reason for generic types in general is the same reason that motivates the creation of an array type template. That is: an array type enhances the ability of its base type in a certain way.

int is a number. Int [] is a collection of numbers; we multiplied the concept of a number by the concept of a set of numbers. The customer represents the customer. Customer [] represents the concept of a collection of customers. We have strengthened the concept of customer to the concept of customer collecting. A mapping from type T to type T [] represents an abstract concept of the general gain of a type instance for a collection of type instances.

The same justification motivates all generic types. The Nullable<T> type enhances the concept type of "this thing can be an instance of a type." The IComparable<T> type reinforces the type to the concept "an instance of this type can be ordered in relation to another instance". And so on. Each generic type is similar to an array template: it represents a type reinforcement into a new type that provides new operations for this type.

In short: the purpose of a type system is to give you the opportunity to come up with your own type amplifiers and manage these amplifications using a type system .

+15
source share

We use generics when we need a "higher order" of polymorphism, akin to compiling duck print . When we say Foo<T> , we mean that Foo<> depends on some property that any possible T can have, and either this T has this property, or the code does not compile.

When we say x = x + 1 , we mean that T can have 1 added to it, and that the return type is T

+8
source share

But why do we even need to have it in common?

If you like, you can also create many custom classes: StringList , IntList , DoubleList , etc. But the generic point is that you can define your class once, and it works for all objects.

And x = x + 1 , where x is of the generic type T , requires that the actual type either support adding with int naturally, or have operator + overloaded with int as the second type.

+3
source share

In fact, I am working on an atm site where generics make my work a lot easier. I need to access a lot of information from the database, since the whole site is managed by the database, so I really wanted to have one class to implement the database functionality. This class inherits more classes that know how to deal with their respective data.

For example, I have a Products class that deals with Products data and a Themes class that deals with topics, etc. Well, all of these classes need a common format for reading and writing. So, I created a recording class that handles this.

Now, where does the Generics game begin. I created the Product class, Theme class, etc.,. with strongly typed members like Name, Manufacturer, ThemeId, however the Records class has no idea how to deal with them. Thus, the database class is of a type related to a particular class, Product, Theme, etc.,. and the recording class also uses the Generic type, so I can write code like ...

 Product.Name = "Cool Product"; 

then save it as ...

 Products.InsertRecord(Product coolProduct); 

Not only does it save a lot of input, but it allows me to have one class that handles all the dirty work, while these little stub classes provide me with a readable, strongly typed interface.

In any case, sorry for the long branch. Hope this helps you understand the power of generics, at least in this case.

+3
source share

For your first question, you can choose List<string> over string[] if you want to dynamically add strings to the list - the array is a fixed size.

0
source share

Since while the string [] is supported (i.e., the type of the custom array is subtracted), the array has: * Less functional than a list or even IList * - an array, so this does not work for other types of collections. What about dictionaries?

If I cannot do my own manipulations in my methods, how can generics help me anyway?

This is a bit like the question: β€œIf I start a vegetarian restaurant, what's good, can I buy steaks from my vendor?”

Basically, when your projects become more complex, you will write your own manipulations in methods. You will do everything that makes sense.

0
source share
 public foobar<T>{ public Action<string,T> SomeAction; public string SomeString; public foobar(Action<string,T> s,string m){ SomeAction=s; SomeString=m; } public void Run(T foo){ SomeAction(SomeString,foo); } } 

Without generics, you will need to write a different class for each opportunity or some other complex action to get the desired results. Generics makes things a little more elegant.

0
source share

string[] gives us an array of fixed size. To have a list of dynamic sizes, we need a class. Therefore, if we need a list of strings, we may need to create a StringList class. For doubles DoubleList. And so on. But what about these classes is unique to these types? Nothing. So instead, we create a generic List <> class that can be of any type. Instead of over and over again creating the same class for different types, generics save us some work.

As for the problem x = x + 1 , you should expect T to have a + operator that accepts int on the right side. If this is not the case, it will cause a runtime error. If so, then this code will assign x to the output operator + with x and 1 as arguments.

There are many other cases where there are no unique operations performed, and the class / method must work with several types. These are also cases where generics are important and useful.

You really need to decide when and where to use them in your code. If you run into a problem where they are the best answer, excellent. Use them. Otherwise, do not. Just do not disqualify them as a solution, because they have never been the answer to your specific problem.

0
source share

A good example of my own work experience was Linq-To-SQL type management. One of the main operations that I must perform when creating a new database object is:

  • Check if the requested object exists in the local cache.
  • Else; Check if the requested object exists in the database.
  • Else, create a new object with the provided parameters.

There are about 100 different types of objects in this particular project, so writing this code for each of them will be cumbersome at best, even with a script, and then what will we do if we need to change something regarding the method

Using generics along with restrictions, I can do something like this:

 public class SQLObjectManager<TEntity> where TEntity : class, new() { public TEntity GetObject(int year, int stateID) { if( /* entity found in cache */) return GetFromCache(year,stateID); if( /* entity found in db */) return GetFromDB(year,stateID); TEntity entity = new TEntity(); entity.Year = year; entity.StateID = stateID; return entity; } } 

In addition to checking the type of compilation time, I now have a single function to implement and support instead of a new version for each table in my database.

0
source share

Please note: if you come from the background of C ++, then the generated C # templates and C ++ templates are similar. Although, I believe that they really work differently.

There are generics for writing code that can be reused for different types. Generics, increases type safety, reduces casting and boxing.

Suppose you need a stack of integers; the solution would have to consist of an integer stack class. Then for each required data type (float, string, etc.) you must write separate versions of the class; here you will realize that this will tend to code duplication.

Another solution would be to write a stack that is generalized using an object as an element type:

What about the next one?

 MyGenericStack<string> stringStack = new MyGenericStack<string>(); stringStack.Push("One"); stringStack.Push("Two"); stringStack.Push("Three"); MyGenericStack<int> intStack = new MyGenericStack<int>(); intStack.Push(1); intStack.Push(2); intStack.Push(3); MyGenericStack<CustomObject> customObjectStack = new MyGenericStack<CustomObject>(); customObjectStack.Push(new CustomObject(1)); customObjectStack.Push(new CustomObject(2)); customObjectStack.Push(new CustomObject(3)); 

The following is a general class

 public class MyGenericStack<T> { int position; T[] data = new T[10]; public void Push(T obj) { data[position++] = obj; } public T Pop() { return data[--position]; } public void Show() { for (int i = 0; i < data.Length; i++) { //Console.WriteLine("Item: {0}", data[i]); //MessageBox.Show(String.Format("Item: {0}", data[i])); } } } 

Yes, I know, now you would fall in love with Generics too !

Btw, if you ever plan on comparing inheritance and generics, remember that inheritance is reused with a base type, whereas generics express reuse with a template type.

0
source share

All Articles