C# ADVANCED
Content
Generics
Iterators
Delegates
Events
Lambda Expressions
LINQ
Example: SmartArray
Generics
Generics
- Concept of type parameters
- Defer spec of 1+ types until class or method is instantiated
public class GenericList<T>{ .... void AddInput(T input) { .. } } class Program { private class SomeClass {} static void Main() { GenericList<int> list1 = new GenericList<int>(); GenericList<string> list2 = new GenericList<string>(); GenericList<SomeClass> list3 = new GenericList<SomeClass>(); } }
Generics #2
- Maximize code reuse, type safety and performance
- No run-time casts or boxing operations
- Create generic interfaces, classes, methods, events and delegates
- Constrain to certain data types
- Generic collection classes: most common usage
- .NET holds generic collection classes in
- System.Collection.Generic
- Use reflection to get information on generic data types at run-time
Generics #3
where T : struct // T must be value type
where T : class // T must be reference type
where T : new() // T must have public parameterless constructor
where T : <base class name> // T must derive from specified base class
where T : <interface name> // T must implement interface
where T : U // T must be or derive from parameterized U
// E.g.
class EmployeeList<T> where T : Employee, IEmployee, new() { .. }
class Base { .. }
class Test<T,U>
where T : struct
where U : Base, new()
{ .. }
Iterators
Iterators
- Step through collections
- Use return yield statement to return each element at a time
- When yield return is reached, current position is remembered
- Execution is restarted from that location the next time
- Can be used in foreach statement or LINQ query
static void Main() { foreach(var num in someNums()) { Console.WriteLine(num); } } public static IEnumerable someNums() { yield return 3; yield return 5; yield return 9; }
Iterators #2
static void Main() {
Days days = new Days();
foreach(var day in days()) {
Console.Write(day + " ");
}
}
public class Days : IEnumerable {
private string[] days = { "Sun", "Mon", "Tue",... };
public IEnerumator GetEnumerator() {
for(int i = 0; i < days.length; i++) {
yield return days[i];
}
}
}
Delegates
Delegates
- Reference to methods with parituclar parameter list and return type
- Associate instance with any compatible method
- Call, invoke method through delegate instance
- Used to pass methods as arguments to other methods
- Event handlers
public delegate int PerformCalc(int x, int y);
Delegates #2
public delegate void Del(string message); public static void DelegateMethod(string message) { // ... } public static void DelegateMethod2(string message) { // ...} static void Main() { Del handler = new Del(DelegateMethod);
Del handler2 = DelegateMethod2; handler("hi"); MethodWithCallback(1,2, handler); } public void MethodWithCallback(int param1, int param2, Del callback) { callback("Params: " + param1 + param2); }
Delegates #3
Anonymous methods
delegate void Del(int x);
Del d = delegate(int k) { // ... };
MethodWithCallback(1,2, delegate(string str) { // ... });
Events
Events
- Notify subscribers on certain events
- Publisher: class that sends events
- Subscriber: receive events and perform operations
- Event can have multiple subscribers
- Subscriber can handle multiple events from multiple publishers
- Events without subscribers are never raised
- E.g. Button clicks in GUI, network application, ...
- In .NET events are based on the EventHandler delegate and EventArgs base class
Lambda Expressions
Lambda Expressions
- Anonymous functions
- Helpful in many cases (e.g. LINQ queries)
- Lambda operator =>
- Input params on the left side
- Expression or statement block on the right side
-
delegate int del(int i); static void Main() { del myDelegate = x => x + x; int j = myDelegate(5); // j? }
Lambda Expressions #2
(x,y) => x == y
(int x, string s) => s.Length > x
() => SomeMethod()
n => { string s = n + " World"; Console.WriteLine(s); };
int outerVariable = 3;
i => { return outerVariable + 5 };
LINQ
LINQ
- Language-integrated query (LINQ)
- Queries are first-class language constructs
static void Main() { int[] primeNums = new int[] { 2, 3, 5, 7,... }; IEnumerable<int> primNumsGT10 = from primeNum in primeNums where primeNum > 10 select primeNum; foreach(int p in primNumsGT10) { Console.WriteLine(p); } // 11, 13, 17, ... }
LINQ #2
- Query describes what data to retrieve from given data source
- Also specify shape and organization of returned data
- Data sources
- SQL database table
- ADO.NET DataTable
- XML file
- In-memory collection
- For the application there is only
- IEnumerable<T> or
- IQueryable<T>
- E.g. IEnumerable<XElement> for LINQ to XML
LINQ #3
Query can do 3 things
- Retrieve subset, produce new sequence without modifying elements (incl. sort and group)
- Retrieve subset, transform them to new type of object
- Retrieve singleton value about data source
- E.g. num elements
LINQ #4
-
Query expression consists of a set of clauses
- written in declarative syntax similar to SQL
- Each clause contains 1+ C# expressions
- May also be query expressions
- Begin with a from clause
- Must end with a select or group clause
- Inbetween there are optional clauses
- where
- oderby
- join
- let
- additional from clauses
LINQ #5
- Query variable
- variable that stores the query
- does not hold the results
- LINQ expression not evaluated immediately
var query = from ....... ; // query variable query // query gets evaluated here, d hols result elements foreach(var d in query) { // ... }
References
Thank you for your attention!
C# ADVANCED
By dinony
C# ADVANCED
- 284