CS3505/5020 Software Practice II A few C# goodies Homework Help Demos (vector math, tools for coding, etc) CS 3505 L05 - 1
Generics public class List< < T T > > public class List { { private T private T [] elements; [] elements; private int private int count; count; public void Add( Add( T T element) { element) { public void if (count == elements.Length if (count == elements.Length) ) Resize(count Resize(count * 2); * 2); elements[count++] = element; elements[count ++] = element; } } List< List < int int > > intList intList = new List = new List< < int int > >(); (); public T public T this[int this[int index] { index] { get { return elements[index get { return elements[index]; } ]; } intList.Add(1); // No boxing intList.Add(1); // No boxing set { elements[index elements[index] = value; } ] = value; } set { intList.Add(2); // No boxing intList.Add(2); // No boxing } } intList.Add("Three"); intList.Add("Three "); // Compile- // Compile -time error time error public int public int Count { Count { int i = intList[0]; i = intList[0]; // No cast required int // No cast required get { return count; } get { return count; } } } } } CS 3505 L05 - 2
Generics � Note, similar in syntax to C++ – But much, much different in implementation � Generics allow us to make classes that use parameterized types – Instead of using object (everything is an object) – Better type checking (adding a string to a List<int> doesn’t work) – No need to box and unbox for primitive types – Compile time type checking removes the need for run-time checks » This leads to better performance. � Generics apply to classes, interfaces, structs, delegates and methods – You can have generic methods without needing a generic class. CS 3505 L05 - 3
Generics � Types can be constrained � The where keyword allows us to state that the type that is bound to the type parameter must have the type of the where statement – So, if we need to say that a type has to implement an interface, or extend a class, we can enforce that at compile time � We can also constrain a type parameter to be a class class Dictionary<K,V>: class Dictionary<K,V>: – Or interface, struct, etc. IDictionary<K,V> <K,V> IDictionary where K: IComparable where K: IComparable<K> <K> where V: IKeyProvider where V: IKeyProvider<K> <K> { { public void Add(K Add(K key, V value) { key, V value) { public void ... ... } } } CS 3505 L05 - 4
Generics � The most obvious use of generics is in container or collection classes – But there are plenty of other uses (IComparable<T> is a good example) � Generics are not quite the same as template classes in C++ – Generics are only types. C++ can have primitive types as template parameters. » (template class C<typename T, int n>) – Rules for generics are simpler than C++ – C# can try to infer the type of a parameterized type (C++ can not). string[] names = Utils.CreateArray Utils.CreateArray<string>("", 10); <string>("", 10); string[] names = int[] numbers = [] numbers = Utils.CreateArray Utils.CreateArray< <int int>( >(- -1, 100); 1, 100); int string[] names = string[] names = Utils.CreateArray Utils.CreateArray("", 10); ("", 10); int[] numbers = Utils.CreateArray( [] numbers = Utils.CreateArray(- -1, 100); 1, 100); int CS 3505 L05 - 5
Generics and Java 1.5 � Java 1.5 did add generics, but there are some differences – Java 1.5 made no changes to the VM. As such… – Java 1.5 generics can’t have primitive types as a parameterized type. (no List<int> in Java 1.5) – Generic information “erased at compile-time” (no generics in reflection, complied classes) – No gain in performance over “object-based” collections. CS 3505 L05 - 6
Generic Summary � Generics take a bit to get used to, but it’s not too bad. – Take advantage of the new generic collection classes when you can » System.Collections.Generic – Generic versions in a different namespace than the older versions » Backward compatibility for older codes CS 3505 L05 - 7
Partial Classes � After the complexity of generics, partial classes are easy. � Partial class just allow you to have the code for one class in multiple files – Instead of just one. � Why is this useful? CS 3505 L05 - 8
Partial Classes publ i c par t i al publ i c par t i al cl ass Cust om cl ass Cust om er er { { pr i vat e i nt i nt i d; pr i vat e i d; pr i vat e st r i ng nam pr i vat e st r i ng nam e; e; pr i vat e st r i ng addr ess; pr i vat e st r i ng addr ess; publ i c cl ass Cust om publ i c cl ass Cust om er er pr i vat e Li st <O pr i vat e Li st <O r der s> or der s r der s> or der s; ; { { } } pr i vat e i nt i nt i d; pr i vat e i d; pr i vat e st r i ng nam pr i vat e st r i ng nam e; e; pr i vat e st r i ng addr ess; pr i vat e st r i ng addr ess; pr i vat e Li st <O pr i vat e Li st <O r der s> or der s r der s> or der s; ; publ i c par t i al publ i c par t i al cl ass Cust om cl ass Cust om er er publ i c voi d Subm Subm i t O r der ( O r der or der ) { publ i c voi d i t O r der ( O r der or der ) { { { or der s. Add( or der ) ; or der s. Add( or der ) ; publ i c voi d Subm Subm i t O r der ( O r der or der ) { publ i c voi d i t O r der ( O r der or der ) { } } or der s. Add( or der ) ; or der s. Add( or der ) ; } } publ i c bool publ i c bool HasO HasO ut st andi ngO ut st andi ngO r der s( ) { r der s ( ) { r et ur n or der s. Count or der s. Count > 0; r et ur n > 0; publ i c bool bool HasO ut st andi ngO r der s( ) { ( ) { publ i c HasO ut st andi ngO r der s } } r et ur n or der s. Count or der s. Count > 0; r et ur n > 0; } } } } } } CS 3505 L05 - 9
Partial Classes � Are partial classes good to use? – Where are your class methods? � Some engineering soundness lost for convenience. – Use at your own risk.
Aside Delegate References � In 1.x version of C# we would add to a delegate as: – foo += new delegatename(functionbar); � In the 2.x version the compiler is able to “do the right thing” – foo += functionbar; CS 3505 L05 - 11
Nullable Types � Sometimes, we need to say that something has no value – This is fairly easy with objects, because we can use ‘null’ for no value. – But, this is very hard with primitive types. � For this, we can use nullable types – Nullable types are a great match for databases, because many databases use nulls. – Nullable types can only be value types (primitive types/structs) � The syntax is pretty simple – int? is a nullable integer. – Nullable<T> makes a nullable type out of any value type (primitive or struct) » Will not work with reference types (classes). CS 3505 L05 - 12
Structs and Classes � Are structs a good idea? � Consider Vector2: – Vector2 a, b; – a = new Vector2(3, 20); – b = a; – a.Normalize(); � What is b?
Iterators � To move through collections, we need to support an Enumerator � Let’s look at an example. First, a simple list class. – Note we use a ListEnumerator helper class. publ i c cl ass Li st publ i c cl ass Li st { { i nt er nal obj ect [ ] el em ent s; i nt er nal obj ect [ ] el em ent s; i nt er nal i nt i nt er nal i nt count ; count ; publ i c I Enum publ i c I Enum er at or er at or G G et Enum et Enum er at or ( ) { er at or ( ) { r et ur n new Li st Enum Li st Enum er at or ( t hi s) ; ) ; r et ur n new er at or ( t hi s } } } } CS 3505 L05 - 14
Enumerator: Old Version publ i c cl ass Li st Enum publ i c cl ass Li st Enum er at or er at or : I Enum : I Enum er at or er at or { { Li st l i st l i st ; ; Li st i nt i nt i ndex; i ndex; i nt er nal Li st Enum i nt er nal Li st Enum er at or ( Li st er at or ( Li st l i st ) { l i st ) { t hi s. l i st = l i st ; t hi s. l i st = l i st ; i ndex = - - 1; 1; i ndex = } } publ i c bool bool M oveNext ( ) { ( ) { publ i c M oveNext i nt i nt i = i ndex + 1; i = i ndex + 1; i f ( i >= l i st . count l i st . count ) r et ur n f al se; ) r et ur n f al se; i f ( i >= i ndex = i ; i ndex = i ; r et ur n t r ue; r et ur n t r ue; } } publ i c obj ect Cur r ent { publ i c obj ect Cur r ent { get { r et ur n l i st . el em l i st . el em ent s[ i ndex] ; } ] ; } get { r et ur n ent s[ i ndex } } } } CS 3505 L05- 15
List (New Version) publ i c cl ass Li st publ i c cl ass Li st { { i nt er nal obj ect [ ] el em ent s; i nt er nal obj ect [ ] el em ent s; i nt er nal i nt i nt er nal i nt count ; count ; publ i c I Enum publ i c I Enum er at or er at or G G et Enum et Enum er at or ( ) { er at or ( ) { f or ( i nt i nt i = 0; i < count ; i ++) { f or ( i = 0; i < count ; i ++) { yi el d r et ur n el em el em ent s[ i ] ; ] ; yi el d r et ur n ent s[ i } } } } } } CS 3505 L05 - 16
Recommend
More recommend