In dart programming, all the collections(for ex: list,map, set etc.) are heterogeneous nature by default.
heterogeneous nature means collections can have values of different data types.
For ex :
void main(){
// this heterogeneous list is not defined with specific type. So we can add values of any data type like String, int, boolean etc.
var list=List();
list.add("red");
list.add(1);
list.add(true);
}
We can also have homogeneous collections by defining specific type for the collection.
Homogeneous collection means it can have the values of same data type we have specified while declaring the collection.
For ex :
void main(){
// this list is defined with specific data type “String”. So we can’t add values other than String data types.
var list=List<String>();
list.add("red");
list.add(“green);
list.add(“blue);
}
Heterogeneous Structure(either it is collections, methhods etc.) can be used when you just want to store values of any data type. While, homogeneous collections are used for storing , retriving and manipulating the data of the same type. it’s very tough for hetrogeneous structures to manipulate the data easily. As they can be of any data type.
For ex :
void main(){
var list=List();
list.add("red");
list.add("green");
// value is of int type
list.add(1);
for(int i=0;i<list.length;i++){
//we’ll get an error when i equals to 2 as the value at the index 2 is not of the String data type.
String value=list[i];
print(value);
}
}
Above example, can be solved either storing the each value of list to the variable of that particular data type or type casting while retrieving data. Which is not a proper solution.
A better solution is to use homogeneous collection or methods instead.
Generics are also used for achieving the same i.e.,we are manipulating and storing the values of the same data type. Which is also known as type safety.
What is generics ?
Generics are used to ensure that the Objects or functions we manipulate are of the same data type or say type safe to use.
we can’t hold objects of different types while using generics as it follows type safety.
Generics Syntax :
// here className can be any type of object i.e., String, List, Map or your custom class etc.
// And DataType is the type specified for the values that can be stored in that particular
data structure(here, className is that data structure).
className variableName=new className()
Generics will give you the error at compile time if you store the values other than specified data type.
Let’s take an example to understand the Generics briefly.
For ex :
void main() {
// this generic map is defined with key of int data type and value of String data type.
var map=Map<int,String>();
map[1]="Red";
map[2]="Green";
map[3]="Blue";
map.forEach((k,v)=>print(v));
}
Output :
Red
Green
Blue
This way you don’t need any type casting or worry about any unknow data type conversion errors while you use generic structures.
What is generic Method ?
A generic method is a method that is declared with the type parameters.
Let’s take an example of generic method.
For ex :
void main(){
int rank = 1;
double number = 0.5;
String value = "test";
print("Integer Value : ");
getDisplayValue(rank);
print("Double Value : ");
getDisplayValue(number);
print("String Value : ");
getDisplayValue(value);
}
//to make a function generic we add <T> after the name of the function. <T> stands for the type of the class like String or int or List etc. The compiler will cast the passed parameter to the appropriate base class object and let the function accept that type parameter.
getDisplayValue<T>(T result) {
print(result);
}
Output :
Integer Value :
1
Double Value :
0.5
String Value :
test
Above function: getDisplayValue(T result) can also be replaced as below function. Object is the parent class of each class. So whatever type of parameter will you pass will be converted to the type of base class Object. So, there will be no compile time or runtime error as it is casted properly to the base class.
getDisplayValue(Object result) {
print(result);
}
In above example, we have created a generic method of Type T which can accept the parameter of type T. Here adding means that the arguments passed to the method is of Type T and is acceptable as they are also converted to the appropriate base class.
Practice this concept more and more to understand this complex and critical concept. Generics will be very helpful to achieve code reusability and code efficiency while developing bigger projects.
Feel free to ask your questions in the comment section. Keep reading and commenting your suggestions to make toastguyz a better site to learn different programming languages.