1 / 34

Programming in C# Extension Methods

Programming in C# Extension Methods. CSE 459.24 Prof . Roger Crawfis. Extension Methods. Can add methods to other classes Let me repeat that: Can add methods to other classes any methods (although they look static) only from static classes

john
Télécharger la présentation

Programming in C# Extension Methods

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programming in C#Extension Methods CSE 459.24 Prof. Roger Crawfis

  2. Extension Methods • Can add methods to other classes • Let me repeat that: Can add methods to other classes • any methods (although they lookstatic) • only from static classes • When you import a namespace that has extensions, these are added to classes • once imported, called as usual instance methods • Local methods take precedence

  3. Extension Methods publicstaticclassExtensions   { publicstaticint ToInt32(thisstringintegerString) { returnInt32.Parse(integerString);     } publicstatic T[] Slice<T>(this T[] source, intstartIndex, int count)     { if(startIndex < 0 || count < 0 || (source.Length - startIndex) < count) thrownewInvalidArgumentException();         T[] result = new T[count]; Array.Copy(source, startIndex, result, 0, count); return result;     } }

  4. Extension Methods • Properties, events and operators can not have extension methods. • Equivalent to calling the static method • Can only access public methods, etc. • Allows for chaining method calls. • More later when we talk about LINQ.

  5. Extension Method Example publicstaticclassMyExtensions {       publicstatic IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int count) {           Queue<T> saveList = new Queue<T>(); int saved = 0; foreach (T item in source)         { if (saved < count)             { saveList.Enqueue(item);                   ++saved; continue;               } saveList.Enqueue(item); yieldreturnsaveList.Dequeue();           } yieldbreak;     } } http://blogs.msdn.com/ericwhite/archive/2008/11/14/the-skiplast-extension-method.aspx

  6. Extension Method Example classProgram { staticvoid Main(string[] args)    { int[] a = new[] { 1, 2, 3, 4, 5 }; var b = a.SkipLast(2);  foreach (var item in b) Console.WriteLine(item); var c = new List<string>() { "one", "two", "three", "four", "five"  }; var d = c.Skip(1).SkipLast(1); foreach (var e in d) Console.WriteLine(e);      } } 1 2 3 two three four

  7. Programming in C#Extension Methods CSE 494R (proposed course for 459 Programming in C#) Prof. Roger Crawfis

  8. Programming in C#Types - Misc CSE 494R (proposed course for 459 Programming in C#) Prof. Roger Crawfis

  9. Initializers • We already know how to initialize basic types: int index = 0; string message = “Save the Cheerleader”; • And complex types using constructors: Person paul = new Person(“Paul”, “Newman”); IList<string> words = new List<string>(35); • Can also use initializers to set properties and initialize collections.

  10. Initializers • Can initialize fields or properties. • new C(1, 2) {Name=“my class”}; • Works if public field or a property with public set • Point a = new Point { X = 0, Y = 1 }; • Can be nested (eg. Rectangle with two Points) • Collection initializers • List<int> digits = new List<int> { 0, 1}; • Must implement System.Generic.ICollection<T>

  11. Initializers Example publicclassStudent{ publicstringfirstName; publicstringlastName; } publicclassScienceClass{ publicStudent Student1, Student2, Student3; } staticvoid Main(string[] args){ var student1 = newStudent { firstName = "Bruce", lastName = "Willis“ }; var student2 = newStudent { firstName = "George", lastName = "Clooney"}; var student3 = newStudent { firstName = "James", lastName = "Cameron“ }; varsClass = newScienceClass { Student1 = student1, Student2 = student2, Student3 = student3 }; }

  12. Initializers Example // Using a Constructor Person p = newPerson("John", "Doe", "602-123-1234"); // Using Properties and an initializer Person p = newPerson() { FirstName="John", LastName="Doe", Phone="602-123-1234", City="Phoenix"}; // Adding a composite type Person p = newPerson() { FirstName = "John", LastName = "Doe", Address = new Address() { Street = "1234 St.", City = "Phoenix“ } };

  13. Implicitly Typed Variables • Type of the variable induced from expression • Must include an initializer • Can not be null. vari = 5; var s = "Hello"; var d = 1.0; // Did you really mean a double? var orders = new Dictionary<int,Order>(); var a = new Point { X = 0, Y = 1 };

  14. Implicitly Typed Variables • Implicitly typed arrays • var a = new[ ] { 1, 10, 100, 1000 }; • Must have consistent types or have implicit conversions

  15. Anonymous Types • var x = new {p1 = 10, p2 = “name”}; • x is an anonymous type • An anonymous type can not be referred to by name in a program. • Structural type equivalence • Two anonymous types can be compatible • Why in the world would we want these? • Again, needed/useful for LINQ.

  16. Anonymous Types Example protectedobjectAnonymousTypes()    { // *** Create Complex Types 'on the fly‘ var Customer = new {             Company = "West Wind",             Name = "Rick",             Entered = DateTime.Now, BillRate = 150M,             Contacts = new {                 Phone = "808 121-1211",                 Fax = "808 231-1211",                 Email = rick@west-wind.com             }         }; return Customer;     } http://www.west-wind.com/weblog/posts/189329.aspx

  17. Programming in C#Types - Misc CSE 494R (proposed course for 459 Programming in C#) Prof. Roger Crawfis

  18. Programming in C#Anonymous Methods CSE 494R (proposed course for 459 Programming in C#) Prof. Roger Crawfis

  19. Anonymous Method Example • Becomes quite cumbersome to create little methods for each specialization. • These methods are only used in one context. • The use and declaration are disjoint. • Would be nice to have the declaration in-line. personList.RemoveAll( delegate(Person person) { returnperson.DateOfBirth.Year < 1980; });

  20. Anonymous Methods • Delegates are clumsy: programmer has to name the function and “closure-convert” by hand • C# 2.0 introduced anonymous methods • No name • Compiler does closure-conversion, creating a class and object that captures the environment e.g. bool b = xs.Exists(delegate(int x) { return x > y; }); Local y is free in body of anonymous method

  21. Can be simplified as follows Button.Click += delegate { Console.WriteLine("clicked"); }; Formal parameters can be omitted if they are not used in the method body Anonymous Methods • Further simplification delegate void EventHandler (object sender, EventArgs arg); Button button = new Button(); Button.Click += delegate (objectsender, EventArgsarg) { Console.WriteLine("clicked"); };

  22. dummy object 0 add delegate x++; return x; Outer Variables • If anonymous methods access variables of the enclosing method, these variables are evacuated into a dummy object (capturing) • The anonymous method and the enclosing method itself are then using a single evacuated variable • delegateintAdder(); • staticAdderCreateAdder() {                • int x = 0; • returndelegate { x++; return x; }; • } • publicstaticvoid Main() { • Adder add = CreateAdder(); • Console.WriteLine(add()); • Console.WriteLine(add()); • Console.WriteLine(add()); • add = CreateAdder(); • Console.WriteLine(add()); • Console.WriteLine(add()); • Console.WriteLine(add()); • } 2 3 1 The dummy object lives as long as the delegate object 1 2 3 1 2 3 Output:

  23. Anonymous Method Example delegatevoidMyDelegate(); classProgram { staticMyDelegateFoo() { int x = 1; Console.WriteLine("Foo: x = {0}", x); MyDelegate d = delegate { x++; Console.WriteLine("delegate: x = {0}", x); };         d();  d(); Console.WriteLine("Foo: x = {0}", x); MyDelegate d2 = delegate { x += 10; Console.WriteLine("second delegate: x = {0}", x); };         d2();  d(); Console.WriteLine("Foo: x = {0}", x); return d2;     } --- Main: Foo()(); Foo: x = 1 delegate: x = 2 delegate: x = 3 Foo: x = 3 second delegate: x = 13 delegate: x = 14 Foo: x = 14 second delegate: x = 24 --- Main: Foo()(); Foo: x = 1 delegate: x = 2 delegate: x = 3 Foo: x = 3 second delegate: x = 13 delegate: x = 14 Foo: x = 14 second delegate: x = 24 staticvoid Main(string[] args) { Console.WriteLine("--- Main: Foo()();"); Foo()(); Console.WriteLine("--- Main: Foo()();"); Foo()();     } }

  24. Programming in C#Anonymous Methods CSE 494R (proposed course for 459 Programming in C#) Prof. Roger Crawfis

  25. Programming in C#Lambda Expressions CSE 494R (proposed course for 459 Programming in C#) Prof. Roger Crawfis

  26. Lambda Expressions • Generalized function syntax •  x . x + 1 • in C# 3.0, have x => x + 1 • From anonymous delegate syntax: • delegate(intx) { return x + 1;} • Can have implicitly typed variables • Can have more than one variable • Can have expression or statement body

  27. Lambda Expressions • Expression or statement body • Implicitly or explicitly typed parameters • Examples: x => x + 1 // Implicitly typed, expression body x => { return x + 1; }// Implicitly typed, statement body (int x) => x + 1 // Explicitly typed, expression body (int x) => { return x + 1; } // Explicitly typed, statement body (x, y) => x * y // Multiple parameters () => Console.WriteLine() // No parameters personList.RemoveAll(p => p.DateOfBirth.Year < 1980);

  28. Lambda Expressions • Lambda expressions participate in inference process of type arguments of generic methods • In initial phase, nothing is inferred from arguments that are lambda expressions • Following the initial phase, additional inferences are made from lambda expressions using an iterative process

  29. Lambda Expressions • Type inference public static IEnumerable<S> Select<T,S>( thisIEnumerable<T> source, Func<T,S> selector) { foreach(T element in source) yield return selector(element); } • If call Select(customers, c => c.Name); • T, S mapped to appropriate types

  30. Lambda Expressions • Generic extension method example: • Calling extension method with lambda expression: List<Customer> customers = GetCustomerList(); IEnumerable<string> names = customers.Select(c => c.Name); • Rewriting extension method call: IEnumerable<string> names = Sequence.Select<T, S>(customers, c => c.Name); • T type argument is inferred to Customer based on source argument type Sequence.Select<Customer, S>(customers, c => c.Name) • c lambda expression argument type is inferred to Customer Sequence.Select<Customer, S>(customers, (Customer c) => c.Name) • S type argument is inferred to string based on return value type of the lambda expression Sequence.Select<Customer, string>(customers, (Customer c) => c.Name) publicstaticclassSequence {    publicstatic IEnumerable<S> Select<T,S>(this IEnumerable<T> source, Func<T, S> selector) { foreach (T element in source) yieldreturn selector(element); }}

  31. Lambda Expressions • A lambda expression is a value, that does not have a type but can be implicitly converted to a compatible delegate type delegateR Func<A,R>(A arg); Func<int,int> f1 = x => x + 1; Func<int,double> f2 = x => x + 1; Func<double,int> f3 = x => x + 1; // Error double -> int

  32. Lambda Expressions • Given the code delegateR Func<A,R>(A arg); staticZ F<X,Y,Z>(X x, Func<X,Y> f1, Func<Y,Z> f2) { return f2(f1(x)); } • What does the following produce?F("1:15:30", s => TimeSpan.Parse(s), t => t.TotalSeconds)

  33. Extension Methods, … • Try this at home! Let’s wrap this discussion up by combining extension methods, implicit types, anonymous types and lambda expressions to create a complex process chain: var processes = System.Diagnostics.Process.GetProcesses() .Where(proc => proc.WorkingSet64 > 20 * 1024 * 1024) .OrderByDescending(proc => proc.WorkingSet64) .Select(proc => new { Identifier = proc.Id, Name = proc.ProcessName }); • foreach (var process in processes) • Console.WriteLine("Identifier = {0}, Name = {1}", process.Identifier, process.Name);

  34. Programming in C#Lambda Expressions CSE 494R (proposed course for 459 Programming in C#) Prof. Roger Crawfis

More Related