Programming C#

Florian Rappl, Department of Theoretical Physics, University of Regensburg

Programming C#

Day 3: Lambda expressions, Delegates, extension methods, LINQ and debugging

Content

  • A simple Windows Forms project
  • Anonymous methods with lambda expressions
  • What is a delegate?
  • Anonymous objects
  • Extension methods
  • Example of extension methods: LINQ
  • Auto properties
  • Advanced debugging

A simple WinForms project

  • Let's create a simple calculator!
  • What is needed?
  • How should the buttons work?
  • Using the designer for creating events
  • Understanding partial classes
  • Advanced topic: Separation of concerns

→ Example - A simple calculator

PocketCalc.zip

Anonymous methods

  • An anonymous method is one that has no name
  • In C# there is an easy way of creating those, using =>
  • This is the so called fat arrow operator
  • Example: (x, y) => x * x + y
  • Or: x => { return x > 0 ? -1 : (x < 0 ? 1 : 0); }
  • Omit round brackets is possible if just 1 argument
  • Curly brackets (and return) can be omitted if single statement

Delegates

  • How to use anonymous methods if they have no name?
  • A pointer to the function is required
  • delegate [RET] [NAME]([ARGUMENTS]) solves this problem
  • This is like a managed function pointer
  • There are already some generic delegates like Func<TReturn>
  • Use: Func<double, double> squ = x => x * x;
  • They can be used like functions, e.g. squ(2)

→ Example - Lambda expressions

Lambda.cs

Anonymous objects

  • C# lets us also create anonymous objects
  • Here the type is unknown, it will be compiler generated
  • new { Name = "Florian", Age = 28 } creates such an object
  • Usage: (temporary) data-encapsulation
  • Advantage: No need to write a whole class for it
  • Disadvantage: Access to members only in local method
  • Passing such an object is only possible as object

Inferring types (var)

  • Problem: What's the type of the anonymous object?
  • We do not know, it is compiler generated...
  • Therefore can only use object, unless ...
  • ... the compiler can detect the type! Keyword: var
  • Simple: var i = 4 will infer Int32
  • Or something more complicated: var pi = 3.14f (Single)
  • Our case: var a = new { Name = "My name" } (who cares!)

Extension methods

  • Scenario: We get a library with cool classes, but ...
  • ... we see that a some useful methods are missing!
  • Usual solution: Write your own (static) methods
  • The first argument would always be an instance of the specific class
  • So why not bring together what belongs together?
  • Extension methods solve this problem with the this keyword
  • Before we had to write something like MyClass.MyMethod(a)
  • Now we can just write a.MyMethod() (shorter and more expressive)

Recipe: Extension methods

namespace MyExtensionMethods
{
	static class ExtMethods {
		public static void Dump(this string s) {
			Console.WriteLine(s);
		}
	}
}
			

→ Example - Extension methods

Extensions.cs

Language Integrated Query (LINQ)

  • A set of really useful extension methods
  • The required namespace is System.Linq
  • Every IEnumerable<T> has LINQ methods
  • Purpose: Run queries of (large) datasets
  • Advantage: Reduction of code
  • Highly useful: lambda expressions, anonymous objects
  • Sort some array e.g. double[] a? a.OrderBy(m => m)
  • Get even elements of int[] a: a.Where(m => m % 2 == 0)

LINQ hierarchy

Important facts about LINQ

  • foreach is more expensive than for
  • There is some overhead associated with LINQ statements
  • LINQ statements are deferred, i.e. only performed if requested
  • If your dataset changes, the LINQ result will change as well
  • IEnumerable<T> is in-memory query
  • IQueryable<T> is for remote-data
  • Important difference that does not matter for us (no remote data)

→ Example - LINQ

Linq.cs

Automatic property generation

  • Obviously the C# compiler does a lot for us
  • Writing variables and their properties is still some work
  • Another area where the C# compiler can help us
  • Consider: int a; public int A { /* ... */ }
  • How about: public int A { get; set; }
  • Compiler generates the member variable and associates it
  • Advantage: Sufficient for most cases
  • Disadvantage: Not helpful if we need value validation and more

Warning about auto properties

  • The syntax is the same as with abstract properties
  • The only difference is the abstract keyword
  • Auto prop. are very good in data-encapsulation classes
  • However, they have drawbacks in some cases (as seen)
  • Biggest drawback: We have no direct access to the variable
  • They are a good starter, which can be replaced easily
  • Advice: Use as often as possible, but do not hesitate to extend the code by changing it to a manual property

→ Example - Automatic properties

AutoProp.cs

Advanced debugging

  • Never use a MessageBox or the Console for debugging
  • Best options: Debug or Trace
  • Here output will be send to the output window
  • They are only used if certain definitions are active
  • Also remember that we have the DEBUG definition in debug-mode
  • Recommendation: Just use Debug.WriteLine()
  • Also use breakpoints and (advanced) conditional breakpoints
  • Use the stack-trace for navigation

All available presentations

More questions? Just mail!

MVP

Florian Rappl, MVP Visual C#