C# Generics Flashcards
What is ildasm?
- ships with .net, can show intermediate language code of exes or DLLs
Why generics?
- allow code reuse with type safety
- defer type specification to client
What is a List?
- generic Collection
- basically an array that manages its own size
- List
- can pass in starting size in constructor
- will double in size as list grows … 0,4,8,16 … as items are added
What is Queue?
- similar to list, generic collection
- no add method, use Enqueue
- use Dequeue - returns first in line and removes it from the queue
- FIFO data structure
- use Peek() to look at next item; doesn’t remove from Queue
- can search Queue with .Contains
What is Stack?
- LIFO data structure
- stack.Push() - to add things to stack
- stack.Pop() - most recently added object, then removes from Stack
- stack.Peek() - get last item added but doesn’t remove from Stack
What is a Hashset?
- similar to List
- order of items is not guaranteed
- set.Add() - returns true/false
- won’t accept duplicates
- you can use special operations on Hashsets
- set1.IntersectWith(set2)
- set1.UnionWith(set2)
- set1.SymmetricExceptWith(set2) - returns items in set1 and set2 but NOT in both
- Hashset by default doesn’t know how to compare complex objects; you have to tell it how to compare
What is LinkedList?
- very concerned with order of items
- AddFirst, AddLast, AddBefore, AddAfter
- RemoveFirst, RemoveLast, etc
- very efficient in adjusting the list
What is Dictionary?
- key and value store
- can’t add duplicate keys
- dict.ContainsKey
- there is a SortedDictionary, sorts on key
What is the T?
- type parameter
- the standard is using T
- anything can be used to represent type
What are “Sorted” collections?
- SortedSet - sorted & unique
- SortedList - sorted & memory efficient
- SortedDictionary - sorted, fast inserts & removals
What does Compare typically do?
- comes from C language
- returns an integer
- if 0 then equal
- if less than 0 then first is less than second
- if greater than 0 then first is greater than second
- ex String.Compare(a, b)
How can you convert types?
- doesn’t work on all types, mostly primitive types
- var conv = TypeDescriptor.GetConverter(typeof(T));
- convert.ConvertTo(item, typeof(TOutput))
How do you return data when building your own Enumerator?
- foreach loop of objects
- yield return result
- basically a lazy return
What is included in method signature?
- everything but the return type including any generic type parameters
What are extension methods?
- static class and static methods
- first parameter is “this IBuffer buffer”
3 basic .NET delegate types often used
- Action… action delegate must always return void
- can take up to 16 params using generic type arguments
- Action print = d => Console.WriteLine(d);
- above is anonymous method with lambda expression
- Func is similar but always has to return a value
- last types parameter is output type
- Func add = (x, y) => x + y;
- Predicate always returns a boolean
- Predicate isLessThanTen = d => d < 10;
- Converter converter = d => DateTime.AddDays(d);
- takes TInput, TOutput
Can you constrain generics?
- yes
- you can force to have specific base class, implement an interface, have a constructor, etc
- uses “where” keyword
ex.
IBuffer where T: class, IInterface, new()
- class (or struct) constraint must come first
- can also constrain to a specific Class
- new() constraint, always last
- compiler will check that type has a default constructor
How do you set a generic to it’s default value?
T result = default(T);
What is “out” keyword for generics?
- it is a generic modifier
- it makes a parameter covariant
- covariance only works with delegates and interfaces
- covariance not allowed on methods taking an entity… if you have an Employee repo you don’t want to be able to save a Person even though Employee is derived from Person
- for readonly methods
- allows things to work with more derived types
What is Contravariance?
- opposite of covariance
- allows generic methods to work with objects that are a more derived type
- for write methods
What is invariant?
- by default, generics are invariant
- if I have a repository of Employee i have to continue to treat it as an Employee respository, not a Person or Manager in example
- changes with covariance (out keyword) or contravariance (in keyword)
Repo Example using Covariance and Contravariance
Person -> Employee -> Manager
public interface IReadOnlyRepo : IDisposable { T FindById(int id); IQueryable FindAll(); }
public interface IWriteOnlyRepo : IDisposable { void Add(T newEntity); void Delete(T entity); int Commit(); }
public interface IRepo : IReadOnlyRepo, IWriteOnlyRep
{
}
public class SqlRepo : IRepo where T: class, IEntity { }
What is an Unbound Generic?
- List<>
- Dictionary<>
- Stack<>
can only be used in typeof operator
- opposite is a Closed Constructed Type
Generics and Reflection example
static method to create a list
private static object CreateColl(Type collType, Type itemType) { var closedType = collectionType.MakeGenericType(itemType); return Activator.CreateInstance(closedType); }