110 likes | 314 Views
Generics. Generics in .NET and C#. ”Generic” Programming in C#/Java (as it was until Summer 2005). All classes inherit from Object So we can apply polymorphism and use Object as static type for elements in containers For instance: Object[ ] data this array may take any object as element
E N D
Generics Generics in .NET and C#
”Generic” Programming in C#/Java(as it was until Summer 2005) • All classes inherit from Object • So we can apply polymorphism and use Object as static type for elements in containers • For instance: Object[ ] data • this array may take any object as element • This approach is well known from standard collections as ArrayList, HashMap etc.
Pros and Cons • Pros • heterogeneous collections • ... • Cons • many type casts • not type safe • type checking is done runtime when casting • int and other native (value) type must be wrapped. (boxing – costs runtime overhead) Is this really an advantage?
Programming Error • The program is incorrect, but we don’t detect it • It is preferable, if : • The program doesn’t work correctly, and we are told by some runtime error (exception) • The compiler rejects the program (compile-time error)
Strategy • Do as much error-checking compile-time as possible: • Advantages: • Easier to write correct programs • More efficient program execution (better performance) • Disadvantages: • Restricts programmers creativity (less flexibility) Is this really a disadvantage?
The Idea: Types as Parameters C#/Java before 2005: ArrayList al = new ArrayList(); Customer c= (Customer)al.get(i);//cast Instead we want something like: ArrayList<Customer> al = new ArrayList<Customer>(); Customer c= al.get(i); • The compiler is able to check that only objects with static type Customer is placed in al • So the compiler knows that everything that may come out from al has static type Customer • So static type checking instead of dynamic type checking is possible • Dynamic casting can be avoided (but is not in all implementations) Type parameter
In C#: EmpSeqAppl Employee a1 = new Employee("Joe", "Programmer", 10000); Employee a = new Employee("Curt", "Senior Programmer", 20000); Employee b = new Employee("Carl", "Programmer", 10000); Employee c = new Employee("Karen", "System Programmer", 13000); Employee d = new Employee("Lisa", "Programmer", 11000); Employee e = new Employee("John", "System Engineer", 9000); string s = "HELLOOOO!"; IList<Employee> emps = new List<Employee>(); emps.Add(a1); emps.Add(a); emps.Add(b); emps.Add(c); emps.Add(d); emps.Add(e); //emps.Add(s);//COMPILER ERROR!!!!
But everything comes at a price: • no heterogeneous collections • But that is not so bad... • more complicated type system • more complicated syntax • one needs a pre-processor, giving • slower compilation • more mysterious error messages
Generics vs. Polymorphism • Generics: • all elements has the same static type (not object!) • static typing (compile-time), static binding is possible • For instance trying to insert a float to List<int> l yields an compiler error • Data Structures based on Polymorphism: • elements may have different types, but all must be subtypes of Object • Dynamic type-checking (when casting) • Dynamic binding