I honestly do not know what they are called.
I have been unable to find articles on the internet.
So I understand that you can do something like this:
public struct Pair<T, U>
{
public readonly T Value1;
public readonly U Value2;
public Pair(T fst, U snd)
{
this.Value1 = fst;
this.Value2 = snd;
}
public override String ToString()
{
return "(" + Value1 + ", " + Value2 + ")";
}
public Pair<U, T> Swap()
{
return new Pair<U, T>(Value2, Value1);
}
}
It could be a class instead of a struct as well.
But I am confused, for what purpose? Some kind of performance gain?
As far as I understand, you can use these things (sorry, what IS the name of this?) to hold values.
But wouldn’t you always know what kind of data it should hold?
For example: if you have a product you need to store, you just need to make a product class. Naturally you’d know what kind of data it needs to hold, since you are designing the code.
So yeah, I guess my question is: What is the purpose of this and what are the advantages over normal objects; which you’d specify a lot more
I think I am not being clear. I also want to know: is there ever a good reason to create something like the pair above? over, say, a more specific object, such as storing your product data in a product object, instead of some generic object that can take in everything.
NEW: Even more text:
Also, how the heck can you handle error coding in something completely generic?
I’d fear doing any kind of math manipulation or actually any kind of manipulation, when I have no idea what kind of datatypes I’ll have to handle.
If it requires me to write error-handling for all datatypes out there, then I REALLY can not see the advantages of these generic parameters.
The purpose is genericity. Often, you have a class whose behavior does not really depend on the type it’s used with.
Rather than
Pair, consider the .NET classList<T>. It stores lists of… some type. The list doesn’t, and shouldn’t care what type it stores. It just has to guarantee that only that type can be stored.A
List<string>allows me to store strings. AList<int>allows me to store ints.If we didn’t have generics, we would have to either throw away type safety, and use a single List class which just stores
Object‘s, but then there would be nothing to prevent me from storing anApplein a list ofBananas.Or we could write a new
Listclass for every type we need to store. We could haveListOfApples,ListOfBananas,ListOfIntsand so on.I think generics offer a nicer solution.
The
Pairexample might be a bit less obvious, becauseoften, if we need to store precisely two values, it’s because they have some clear relationship which should be represented by creating a specific object. But sometimes, they don’t. Sometimes they are just “the first value” and “the second value”. Perhaps you have a function which simply returns two values. It’s easier then to return aPair<T1, T2, than to return one value and handle the other by having anoutparameter.You often don’t need a pair, no. But if you really need “a way to store two values of different types inside a single object”, if there is no real behavior associated with it, then a
Pairclass represents that nicely. And then why not make it reusable by allowing the types to change?Simple: .NET doesn’t let you do that. In your Pair example, the compiler will complain if you try to use a function on it which is not guaranteed to be available. In your case, you’ll only be able to use the functions defined on the
Objectbase class (and of course, generic functions and classes which also work on any type).So you can’t use any kind of math manipulation on these generic types. You can’t do much more with them than storing them, and passing them around (and calling
.ToString()).But sometimes, you don’t need anything more than that. For example if you’re just creating a
Listclass, or aPair.You can also specify constraints, narrowing it down a bit. For example:
This will produce a compile error if I try to call it with an
int, but will work with all the variousStreamsubclassees. And now I know a bit more about the class, so I’ll be able to do some operations meaningfully.But going back to error handling, what errors would you need to handle in the
Listclass? Not a lot of errors can occur.You have a class whose job it is to store a variable number of objects of some unknown (but fixed) type. It can insert new objects (which might throw an out of memory exception), and it can retrieve objects. It can let us search for objects, and then of course we might have the error case when the thing we searched for could not be found. But that’s basically it. There is no error handling specific to the generic type. Why would there be? We don’t do anything type-specific to the objects we store, so they don’t really get an opportunity to throw any type-specific errors.