Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Friday, October 24, 2014
( Action | c# | Func )
var a = Days.Mon; var x = Days.Wed; var b = (int)a; var c = (int) x; } } enum Days { Mon = 5, Tue, Wed, Thur, Fri, Sat, Sun };

Interesting: sequence will be 5,6,7…

From http://www.wrox.com/WileyCDA/WroxTitle/productCd-1118612094,descCd-DOWNLOAD.html

// Is k < 10 // cw // k++ for (int k = 0; k < 10; k++){ Console.WriteLine("hello {0}", k); }

Order of execution.

var curr = "£1,234.56"; double number; double.TryParse(curr, NumberStyles.Currency,null, out number);

Interesting!

var sss = new string('c', 10);

Makes 10 c’s

checked { int test = int.MaxValue; test++; //System.OverflowException thrown }


Checking for arithmetic overflow/underflow errors

float zero = 0; float positive = 1 / zero; Console.WriteLine(positive); // Outputs "Infinity" float negative = -1 / zero; Console.WriteLine(negative); // Outputs "-Infinity" int test = int.MaxValue; test++; Console.WriteLine(test); // int.MinValue var x = int.MinValue; checked { int xy = int.MaxValue; //xy++; // Overflow exception } checked{ float xx = float.MaxValue; var xxx = xx + 1; // no exception if (xx == xxx) // loss of equality in rounding Console.WriteLine("true"); // gets here }


number stuff.

class Program { static void Main(string[] args) { var t = new Thing("hello"); } } class ThingBase { public ThingBase(string message) { Console.WriteLine("ctor of thingbase {0}", message); } } class Thing : ThingBase { public string Message { get; set; } public Thing(string message) : base(message) { Console.WriteLine("ctor of customer"); this.Message = message; } }


Calling a base constructor

Implicity vs Explicity Interface impelement http://stackoverflow.com/questions/4103300/why-implement-interface-explicitly

class Program { static void Main(string[] args) { // TeachingAssistant can't see PrintGrades - public not possible IStudent ta = new TeachingAssistant(); ta.PrintGrades(); } } class TeachingAssistant : IStudent { void IStudent.PrintGrades() { throw new NotImplementedException(); } } interface IStudent { void PrintGrades(); }

Interesting explicit interface implementation.

Action and Func

// Action takes parameters but doesn't return Action note = () => Console.WriteLine("hello"); note(); Action<string> thing = x => Console.WriteLine("thing is {0}", x); thing("ahhh"); // Func is a generic type which encapsulates delegates (callable code) Func<float, float> square; square = delegate(float x) { return x*x; }; square = (float x) => x*x ; square = x => x*x ; var result = square(3); Console.WriteLine(result);
| | # 
# Wednesday, October 22, 2014
( c# )

Rule #10 – Avoid Regions

For splitting up large classes / ugly code.  Break code into separate classes

Rule #9 – Use Exceptions for Errors

  • Instead of status codes or booleans
  • but not for control flow (ie plan to throw and catch somewhere else)
  • Should indicate errors in the program
public bool Login(string username, string password){ if (String.IsNullOrEmpty(username)){ // throw an Exception better.. maybe a problem in the caller? throw new ArgumentException("Username is empty"); // not good - implication is username/password combintation didn't work return false; } // ... return true; }

Rule #8 – Avoid Boolean Parameters

// What does true mean? WriteFile(data, true); // better WriteFile(data, flush:True); // A simple wrapper - nice WriteFileAndFlush(data); WriteFile(data); } private static void WriteFileAndFlush(byte[] contents){ WriteFile(contents, true); } public static void WriteFile(byte[] contents) { WriteFile(contents, false); } // Private so API only shows 2 methods above private static void WriteFile(byte[] contents, bool flush){ }

Rule #7 – Avoid Too Many Parameters

4 seems like too much!

If lots, are they grouped together.. ie can I make a Class?

public void LoginUser(string username, string password, IPAddress ipAddress, bool persist){ // ... } // Grouped parameters.. maybe could be validation logic on the class // to ensure have all required pieces of information public void LoginUser(UserLoginRequest request){ }

Rule #6 – Warnings are Errors

“You the developer, against forces of Entropy”!
Anything you can do to keep entropy away and keep code organised and maintained is good.

image_thumb[1]
Warning level 4 is most aggressive setting.  Treat warnings as errors: All

image_thumb[3]

Rule #5 – Encapsulate Complex Expressions

if (account.Balance > 0 && !account.IsVIP && account.DueDate > CurrentDate){ // send off a warning } // encapsule in the account class // instant recognition is good if (account.IsPasDue){ // ... }

Rule #4 – Try and avoid Multiple Exit Points

usually at bottom of method.

if (account.Balance < 1000){ return false; } else if (account.IsPastDue){ return false; } else if (account.IsVip){ return false; } return true; // better var isValid = true; if (account.Balance < 1000){ isValid = false; } else if (account.IsPastDue) { isValid = false; } else if (account.IsVip) { isValid = false; } return isValid;

Rule #3 – Try to avoid Comments

Most comments are trying to describe the purpose or intention of a piece of code

// ensure we don't send a notification to // important people if (account.IsVip && account.IsPastDue){ SendNotification = false; } // Abstracted into a method so don't need the comment! CancelNotificationForVipAccounts();

For shard libraries the VS comments /// are useful for other developers to see in intellisense what your API does.

Rule #2 – Keep Methods Short

Fit on the screen is good!

1-10 pretty safe
20
30+ start to get worried
50+ problem!

Split up by:?

  • Deciding things
  • Doing things

Rule #1 – Keep Classes Small

Large classes try to do too many things, get cluttered

Split up by Roles, Responsibilities, Delegation

| | # 
( c# )

Coding Standards

Consistency through a codebase so reader can follow and not be confused with something out of the ordinary.
Most people use: http://msdn.microsoft.com/en-us/library/vstudio/ms229043(v=vs.100).aspx

Names of methods should contain a verb - http://msdn.microsoft.com/en-us/library/vstudio/ms229012(v=vs.100).aspx

Props: Noun

Bool props affirmative: eg Isxxx, Canxxxx, HasRecords

R#, StyleCop

Naming

// Ahh strInput - not preferrable public bool Test(string strInput) { string strTrimmed = strInput.Replace(" ", ""); string strReversed = new string(strTrimmed.Reverse().ToArray()); return strReversed.Equals(strReversed); } public bool Check(string input) { input = input.Replace(" ", ""); var reversed = new string(input.Reverse().ToArray()); return reversed.Equals(input); } // Good name public bool IsPalindrome(string input) { // Symmetry - forwards and backwards var forwards = input.Replace(" ", ""); var backwards = new string(forwards.Reverse().ToArray()); return backwards.Equals(forwards); }

Building Meaning

Ahh data and no behaviour (mmmm – probably smell)

If you’re not happy with the code, write the API you want to see

[TestMethod] public void DemonstrationOfCreatingAccount() { // lateAccount better, or a Method var account = new Account(); account.Balance = 9000; account.Customer = new Customer(); account.Customer.Address = new Address(); account.Customer.Address.City = "London"; account.Customer.Address.Country = "UK"; account.Customer.IsVip = true; // Not clear that the account is PastDue account.DueDate = DateTime.Now.AddDays(-1); account.Customer.Name = "Penelope"; }
Builder design pattern better (maybe).. eg
AccountBuilder
  .DefaultAccount
   .AsVip
  .LivesIn(“London”)
  .Build

[TestMethod] public void CanCreateAccount(){ // Using a static method instead of newing up an AccountBuilder var account = AccountBuilder.DefaultAccount().Build(); Assert.IsNotNull(account); } } public class AccountBuilder{ // Something that wraps the account being created public static AccountBuilder DefaultAccount(){ return new AccountBuilder(); } public AccountBuilder(){ _account = new Account(); } public Account Build(){ return _account; } private Account _account; }

Starting off on the Builder pattern.

[TestMethod] public void AssignsDefaultValues() { var account = AccountBuilder.DefaultAccount().Build(); Assert.IsTrue(account.Balance > 0); Assert.IsTrue(account.DueDate > DateTime.Now); Assert.IsNotNull(account.Customer.Address.City); Assert.IsNotNull(account.Customer.Address.Country); Assert.IsFalse(account.Customer.IsVip); Assert.IsNotNull(account.Customer.Name); } } public class AccountBuilder{ // Something that wraps the account being created public static AccountBuilder DefaultAccount(){ return new AccountBuilder(); } public AccountBuilder(){ _account = new Account(); _account.Balance = 10000; _account.DueDate = DateTime.Now.AddDays(1); _account.Customer = new Customer(); _account.Customer.Name = "Michelle"; _account.Customer.IsVip = false; _account.Customer.Address = new Address(); _account.Customer.Address.City = "DC"; _account.Customer.Address.Country = "USA"; } public Account Build(){ return _account; } private Account _account;

Chaining:

public AccountBuilder WithLatePaymentStatus(){ _account.DueDate = DateTime.Now.AddDays(-1); // As we're chaining, need to keep returning ourselves return this; }

Code that expresses intention better

| | # 
# Tuesday, October 21, 2014
( c# | Functional )

Building abstractions using functions

Build own primitives.. classes last module… methods/functions this module

Higher order functions

Take 1 or more fns as an input, or return fns

internal static class Program2 { private static void Main(string[] args) { var numbers = new[] { 3, 5, 7, 9, 11, 13, 15 }; foreach (var prime in numbers.FindPrimes()) { Console.WriteLine(prime); } } private static IEnumerable<int> FindPrimes(this IEnumerable<int> values) { //iterate //test if prime //return a difference sequence of ints var result = new List<int>(); foreach (var number in values) { if (IsPrime(number)) { result.Add(number); } } return result; } private static bool IsPrime(int number) { bool isPrime = true; for (long i = 2; i < number - 1; i++) { if (number % i == 0) isPrime = false; } return isPrime; } }

Extension method on IEnumerable<int>

internal static class Program2 { private static void Main(string[] args) { var numbers = new[] { 3, 5, 7, 9, 11, 13, 15 }; // Passing in the IsPrime function into Find foreach (var prime in numbers.Find(IsPrime)) { Console.WriteLine(prime); } } // Find is a higher order function, as it takes another function as a parameter // composable with other functions private static IEnumerable<int> Find(this IEnumerable<int> values, Func<int, bool> test) { //iterate //test if prime //return a difference sequence of ints var result = new List<int>(); foreach (var number in values) { //if (IsPrime(number)) { if (test(number)) { result.Add(number); } } return result; } private static bool IsPrime(int number) { bool isPrime = true; for (long i = 2; i < number - 1; i++) { if (number % i == 0) isPrime = false; } return isPrime; } }

Find is a Higher Order Function.

Lazyness

Lazy evaluation – allows you to write an expression that’s not executed until the last possible moment.  And only if we need the result (program forces us to execute).

  • Avoid expensive calculations that we don’t need
  • Data structures of an infinite size
private static void Main(string[] args) { var numbers = new[] { 3, 5, 7, 9, 11, 13, 15 }; // Passing in the IsPrime function into Find foreach (var prime in numbers.Find(IsPrime).Take(2)) { Console.WriteLine(prime); } } // Find is a higher order function, as it takes another function as a parameter // composable with other functions private static IEnumerable<int> Find(this IEnumerable<int> values, Func<int, bool> test) { //iterate //test if prime //return a difference sequence of ints var result = new List<int>(); foreach (var number in values) { Console.WriteLine("Testing {0}", number); if (test(number)) { result.Add(number); } } return result; }

image
Didn’t expect this. 

image
Swap out the internal list for yield return.

Generates code for IEnumerable under the hood.

Essentially pauses the execution of the method for the caller to process the current result.  When the caller needs the next result, execution will resume where it last left off.

private static void Main(string[] args) { var numbers = new[] { 3, 5, 7, 9, 11, 13, 15 }; // Passing in the IsPrime function into Find //foreach (var prime in numbers.Find(IsPrime).Take(2)) { foreach (var prime in GetRandomNumbers().Find(IsPrime).Take(2)) { Console.WriteLine(prime); } } // Interesting this function stops when 2 primes are found (as Take(2) above) static IEnumerable<int> GetRandomNumbers(){ yield return 3; yield return 6; yield return 8; yield return 9; yield return 11; yield return 13; }

asdf

private static void Main(string[] args) { var numbers = new[] { 3, 5, 7, 9, 11, 13, 15 }; // Passing in the IsPrime function into Find //foreach (var prime in numbers.Find(IsPrime).Take(2)) { foreach (var prime in GetRandomNumbers().Find(IsPrime).Take(2)) { Console.WriteLine(prime); } } static IEnumerable<int> GetRandomNumbers(){ Random rand= new Random(); // Infinite loop while (true){ yield return rand.Next(1000); } }

Nice – tries random numbers until it gets 2 primes.

An infinite sequence of integers

Timing and Retries

Higher order functions not related to querying.

public class Timekeeper { public TimeSpan Measure(Action action) { var watch = new Stopwatch(); watch.Start(); action(); return watch.Elapsed; } } internal static class Program2 { private static void Main(string[] args) { var timekeeper = new Timekeeper(); // Passing in a function to Measure var elapsed = timekeeper.Measure(() => { foreach (var prime in GetRandomNumbers().Find(IsPrime).Take(2)) { Console.WriteLine(prime); } }); Console.WriteLine(elapsed); }


Interesting! 1:48 of 3:37 in Timing and Retries

public static T WithRetry<T>(this Func<T> action) { var result = default(T); int retryCount = 0; bool succesful = false; do { try { result = action(); succesful = true; } catch (WebException ex) { retryCount++; } } while (retryCount < 3 && !succesful); return result; } private static void Main(string[] args) { var client = new WebClient(); Func<string> download = () => client.DownloadString("http://microsoft.com"); // This is a Higher Order Function, even though it doesn't look like it var data = download.WithRetry();

Interesting!

Partial Application and Currying

Partical application is adapting a function into a function which doesn’t need a paramter

public static Func<TResult> Partial<TParam1, TResult>( this Func<TParam1, TResult> func, TParam1 parameter) { return () => func(parameter); }

Currying .. (Haskall Curry).

public static Func<TParam1, Func<TResult>> Curry<TParam1, TResult> (this Func<TParam1, TResult> func) { return parameter => () => func(parameter); }

Async and Parallel

a benefit of functional..parallelism

AsParallel in TPL.

static void Main(string[] args) { var timekeeper = new Timekeeper(); var elapsed = timekeeper.Measure(() => FindLargePrimes(1, 200000)); Console.WriteLine(elapsed); } private static IList<int> FindLargePrimes(int start, int end) { var primes = Enumerable.Range(start, end - start).ToList(); return primes.Where(IsPrime).ToList(); }

and now in parallel

static void Main(string[] args) { var timekeeper = new Timekeeper(); var elapsed = timekeeper.Measure(() => FindLargePrimes(1, 200000)); Console.WriteLine(elapsed); } private static IList<int> FindLargePrimes(int start, int end) { var primes = Enumerable.Range(start, end - start).ToList(); return primes.Where(IsPrime).ToList(); } private static IList<int> FindLargePrimesInParallel(int start, int end) { var primes = Enumerable.Range(start, end - start).ToList(); return primes.AsParallel().Where(IsPrime).ToList(); }

For more control over the execution

// Expecting a Task which returns an IEnumerable<int> var task = new Task<IEnumerable<int>>( () => FindLargePrimes(3, 100) ); task.Start(); Console.WriteLine("Doing other work"); // Wait until unblocked task.Wait(); foreach (var number in task.Result) { Console.WriteLine(number); }

and more..

// Expecting a Task which returns an IEnumerable<int> var task = new Task<IEnumerable<int>>( () => FindLargePrimes(3, 100) ); // Chaining var task2 = task.ContinueWith((antecedent) => { foreach (var number in antecedent.Result) { Console.WriteLine(number); } }); task.Start(); Console.WriteLine("Doing other work"); // Wait until unblocked task2.Wait();
| | # 
# Friday, October 17, 2014
  • Encapsulation
  • Inhertence
  • Polymorphism

Encapsulation

Glance test… what abstractions are there… ie for a code review, shouldn’t be primitive types around.

class Program { static void Main(string[] args) { var date = new List<DateTime>(); var open = new List<decimal>(); var high = new List<decimal>(); var low = new List<decimal>(); var close = new List<decimal>(); var lines = File.ReadAllLines(args[0]); for (int i = 1; i < lines.Length; i++) { var data = lines[i].Split(','); date.Add(DateTime.ParseExact(data[0], "M/d/yyyy", CultureInfo.InvariantCulture)); open.Add(decimal.Parse(data[1])); high.Add(decimal.Parse(data[2])); low.Add(decimal.Parse(data[3])); close.Add(decimal.Parse(data[4])); } for (int i = 0; i < date.Count - 4; i++) { if (open[i] > high[i + 1] && close[i] < low[i + 1]) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Pivot downside {0}", date[i].ToShortDateString()); } if (open[i] < low[i + 1] && close[i] > high[i + 1]) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Pivot upside {0}", date[i].ToShortDateString()); } } } }

Business logic doesn’t present itself as no abstractions (only primitive abstrations)

The Big Encapsulation

Break up procedures into Methods

Higher density of information

class Program { static void Main(string[] args) { const string filename = "msft.csv"; var ana = new StockQuoteAnalyzer(filename); ana.LoadQuotes(); ana.AnalyzeQuotes(); } } class StockQuoteAnalyzer { private readonly string _filename; readonly List<DateTime> _date = new List<DateTime>(); readonly List<decimal> _open = new List<decimal>(); readonly List<decimal> _high = new List<decimal>(); readonly List<decimal> _low = new List<decimal>(); readonly List<decimal> _close = new List<decimal>(); public StockQuoteAnalyzer(string filename) { _filename = filename; } public void LoadQuotes() { var lines = File.ReadAllLines(_filename); for (int i = 1; i < lines.Length; i++) { var data = lines[i].Split(','); _date.Add(DateTime.ParseExact(data[0], "M/d/yyyy", CultureInfo.InvariantCulture)); _open.Add(decimal.Parse(data[1])); _high.Add(decimal.Parse(data[2])); _low.Add(decimal.Parse(data[3])); _close.Add(decimal.Parse(data[4])); } } public void AnalyzeQuotes() { for (int i = 0; i < _date.Count - 4; i++) { if (_open[i] > _high[i + 1] && _close[i] < _low[i + 1]) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Pivot downside {0}", _date[i].ToShortDateString()); } if (_open[i] < _low[i + 1] && _close[i] > _high[i + 1]) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Pivot upside {0}", _date[i].ToShortDateString()); } } } }

Defining classes to separate rules and responsibilities.. http://www.wirfs-brock.com/DesignBooks.html

Object responsibilities and roles – keep separated:

  • Knowing
  • Deciding
  • Doing

Little Abstractions

6 classes now instead of 2

Is this too much – a big problem in design!  If its a throwaway program, then yes.

  • KISS
  • YAGNI

Design should be iterative, and driven by immediate needs.  Some consideration for what's going to change in the future.  Concrete use/test cases are good.

Replacing dot net primitives, with own abstractions..

Separate

  • Knowing (domain) eg StockQuote encapsulates knowledge (including compares)
  • Deciding (business logic) eg Analyzer, ReversalLocator
  • Doing (input, output to screen etc..)

StockQuoteAnalyzer isn’t tied to the ConsoleApp anymore. Can be used in webapp, service etc..

image

11/14/2004 look for.

image
Opened above the previous high, and below the previous low.

Inheritance

Template method pattern (abstract base class)

But it tightly binds things together.  Bad. Harder to make changes.

Interfaces

A class can implement multiple interfaces.

Directional Dependencies

Passing in a dependency

Modern OOP

  • Encapsulation is king
  • Interfaces and composable
  • Small abstractions are powerful
| | # 
( Dynamic )

.NET4.0 new runtime on top of the CLR to support dynamic languages – DLR.. Ruby and Python.

Why Dynamic?

Static: C#, F#, C

Dynamic: JavaScript, Python,Ruby, PHP .. generally.. allow to modify code and types at runtime.  No compiler.  So only perform type checking at runtime (if at all)

 

When the compiler sees the dynamic keyword, it turns off compile time checks.

class Program { static void Main() { //Object o = GetASpeaker(); // Cooerce GetASpeaker as an Employee //Employee o = GetASpeaker() as Employee; //Use reflection.. if we know there is a Speak method //o.GetType().GetMethod("Speak").Invoke(o,null); //o.Speak(); dynamic o = GetASpeaker(); o.Speak(); } private static object GetASpeaker() { return new Employee { FirstName = "Scott" }; } } public class Employee { public string FirstName { get; set; } public void Speak() { Console.WriteLine("Hi, my name is {0}", FirstName); } }

It works.

Com Interop – Excel

image

Type excelType = Type.GetTypeFromProgID("Excel.Application"); dynamic excel = Activator.CreateInstance(excelType); excel.Visible = true; excel.Workbooks.Add(); dynamic sheet = excel.ActiveSheet; Process[] processes = Process.GetProcesses(); for (int i = 0; i < processes.Length; i++) { sheet.Cells[i + 1, "A"] = processes[i].ProcessName; sheet.Cells[i + 1, "B"] = processes[i].Threads.Count; }

Expando

dynamic expando = new ExpandoObject(); expando.Name = "Scott"; expando.Speak = new Action(() => Console.WriteLine(expando.Name)); //expando.Speak(); foreach (var member in expando) { Console.WriteLine(member.Key); }

prints Name, Speak

Parse an XML file:

// XDocument is in System.Xml.Linc var doc = XDocument.Load("Employees.xml"); foreach (var element in doc.Element("Employees") .Elements("Employee")) { Console.WriteLine(element.Element("FirstName").Value); } // Expando objects in expando var doc2 = XDocument.Load("Employees.xml").AsExpando(); foreach (var employee in doc2.Employees) { Console.WriteLine(employee.FirstName); }

then a simple extension method:

public static class ExpandoXml { public static dynamic AsExpando(this XDocument document) { return CreateExpando(document.Root); } private static dynamic CreateExpando(XElement element) { var result = new ExpandoObject() as IDictionary<string, object>; if (element.Elements().Any(e => e.HasElements)) { var list = new List<ExpandoObject>(); result.Add(element.Name.ToString(), list); foreach (var childElement in element.Elements()) { list.Add(CreateExpando(childElement)); } } else { foreach (var leafElement in element.Elements()) { result.Add(leafElement.Name.ToString(), leafElement.Value); } } return result; } }

CreateExpando is a recursive function that calls itself.

DynamicObject

A bit of work – but lots of power here.

| | # 
( Expression | Func | Linq )

Linq provider with translate linq to SQL (for EF)

Expressions wrap a Func type.

static void Main() { var db = new MovieDB(); IEnumerable<Movie> query = // Lambda expression being passed in - how to filter db.Movies.Where(m => m.Title.StartsWith("Wal")) // Lambda expression - how to filter .OrderBy(m => m.ReleaseDate.Year); foreach (var movie in query) { Console.WriteLine(movie.Title); }
Then look at profiler:

SELECT [Project1].[ID] AS [ID], [Project1].[Title] AS [Title], [Project1].[ReleaseDate] AS [ReleaseDate] FROM ( SELECT DATEPART (year, [Extent1].[ReleaseDate]) AS [C1], [Extent1].[ID] AS [ID], [Extent1].[Title] AS [Title], [Extent1].[ReleaseDate] AS [ReleaseDate] FROM [dbo].[Movies] AS [Extent1] WHERE [Extent1].[Title] LIKE N'Wal%' ) AS [Project1] ORDER BY [Project1].[C1] ASC

Outer query for ordering.  Sub query for filtering – StartsWith “Wal”

How do these Func’s get translated into Expressions that go into SQL Server?

image

Ahh, not selected the extension method for IEnumerable.

Using IQueryable (which derives from IEnumerable).  But all remote linq providers implmement properties which are IQueryable.

No longer take a Func<T>, but an Expression<T>.  Where T is a Func<T>

image

Opaque – only tells us it takes an int, and returns an int.  Doesn’t really see what's inside of that method.

Expression – essentially when the extension method for IQueryable is doing.

write(square(add(1, 3)));

Invoking the square Func no longer works. (method delegate or event is expected)

image

In immediate window:

image

image

NodeType is multiple, left hand side is x, right hand side is x.  Value to produce is Int32.

Compiler doesn’t compile lambda expression to IL, but builds a data structure – an abstract syntax tree, that have objects inside that represent the operations that we have expressed in code.

Up to linq provider to take the data structure and figure out how to translate it.

Comprehension Query Syntax

var query2 = from m in db.Movies where m.Title.StartsWith("L") select m;

C# compiler translates this syntax into extension method calls.

var q2 = db.Movies.Where(x => x.Title.StartsWith("L")) .OrderBy(x => x) .Select(x => x);

Many of these LINQ oriented features are useful for everyday code

  • Functional programming
  • Reduced noise
| | # 
# Thursday, October 16, 2014

TL;DR

· Only handle exceptions that you can actually do something about!!  eg Always enclose every piece of code that is run externally in a try/catch eg File read, webservice call… so can gracefully show the user

· Let the global exception handler for the application (eg via global.asax in MVC) catch/handle/log/redirect to error page for the rest of the exceptions.

- Explore EMLAH

http://www.hanselman.com/blog/GoodExceptionManagementRulesOfThumbBackToBasicsEdition.aspx

Only handle exceptions that you can actually do something about!!

http://stackoverflow.com/questions/14973642/how-using-try-catch-for-exception-handling-is-best-practice

  • Catch all unhandled at a global level, and maybe show to user? and log to file
  • Always enclose every piece of code that is run externally in a try/catch
  • Enclose ops that I know might not work eg IO, division by 0..

This is very bad: as the original exception is lost

catch (Exception ex) {
   throw ex;
}

This is bad. Exception is lost

catch (Exception ex) {
   // do nothing ie swallowing exception
}

This is good. Although code may be redundant (unless you need a Finally?)

catch (Exception ex) {
   throw;
}

This is good as the SomeException will have an inner Exception containing the original exception

catch (Exception ex) {
   throw new SomeException(“Some detailed message”, ex);
}

Throwing

Domain/Business logic

class Program { static void Main() { var person = new Person { Name = "" }; Console.WriteLine(person.Name); Console.ReadLine(); } } public class Person { // Backing field (private) private string name; // Property - used to expose field // Properties allow validation on incoming values public string Name { get { return name; } set { if (String.IsNullOrEmpty(value)) { throw new ArgumentException("Name cannot be null or empty"); } name = value; } } }

Simple throwing an exception

Handling

Inner exceptions:

private static void Main() { try { ReadFromFile(); } catch (Exception ex) { throw new Exception("main", ex); } } private static void ReadFromFile() { string[] lines = File.ReadAllLines("grades.txtx"); foreach (string line in lines) { float grade = float.Parse(line); Console.WriteLine(grade); } }

image

throw new Exception(“main”) is bad – lose the inner!

Custom Exceptions

private static void Main() { ReadFromFile(); } private static void ReadFromFile() { try { string[] lines = File.ReadAllLines("grades.txtx"); foreach (string line in lines) { float grade = float.Parse(line); Console.WriteLine(grade); } } catch (Exception ex) { throw new GradesFileNotFoundException("File not found in the directory", ex); } } // Applicaiton exception is thrown by user program... bad now... public class GradesFileNotFoundException : Exception { public GradesFileNotFoundException() { } public GradesFileNotFoundException(string message) : base(message) { } public GradesFileNotFoundException(string message, Exception inner) : base(message, inner) { } }

**but when are these actually useful?

 

Global Application Handling

private static void Main() { // Global exception handler for a ConsoleApp AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper; ReadFromFile(); } static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine(e.ExceptionObject.ToString()); Console.WriteLine(); Console.WriteLine("Bad things have happened - we've logged the error and sent to devs... Press Enter to continue"); Console.ReadLine(); Environment.Exit(1); } private static void ReadFromFile() { try { string[] lines = File.ReadAllLines("grades.txtx"); foreach (string line in lines) { float grade = float.Parse(line); Console.WriteLine(grade); } } catch (Exception ex) { throw new GradesFileNotFoundException("File not found in the directory", ex); } } // Applicaiton exception is thrown by user program... bad now... public class GradesFileNotFoundException : Exception { public GradesFileNotFoundException() { } public GradesFileNotFoundException(string message) : base(message) { } public GradesFileNotFoundException(string message, Exception inner) : base(message, inner) { } }
http://codebetter.com/karlseguin/2008/05/30/foundations-of-programming-pt-8-back-to-basics-exceptions/
  • Handling
  • Creating
  • Throwing

Handling

Catching exceptions and not actually handling them – Exception swallowing

Creating

using (SqlConnection connection = new SqlConnection(FROM_CONFIGURATION)) using (SqlCommand command = new SqlCommand(“SomeSQL”, connection)){ connection.Open(); command.ExecuteNonQuery(); }

If ExecuteNonQuery throws an exception, this will dispose of the connection.
  • Don't swallow exceptions
  • Don’t catch exceptions unless you can handle them
  • Make use of custom exceptions
| | # 
# Wednesday, October 15, 2014

Language Integrated Query
LINQ provides a general purpose query facility

MS… IEnumerable<T>

static void Main() { // Can hide anything behind IEnumerable eg a database // doesn't define interesting methods.. so MS added extension methods IEnumerable<string> cities = new[] { "Ghent", "London", "Las Vegas", "Hyderbad" }; foreach (var city in cities) { Console.WriteLine(city); } }


Utility class - old way of doing it:

class Program { static void Main() { var date = new DateTime(2002, 8,9); int daysTillEndOfMonth = DateUtilities.DaysToEndOfMonth(date); Console.WriteLine(daysTillEndOfMonth); } } public static class DateUtilities { public static int DaysToEndOfMonth(DateTime date) { return DateTime.DaysInMonth(date.Year, date.Month) - date.Day; } }

By adding this we have an extension method.

class Program { static void Main() { var date = new DateTime(2002, 8,9); // Using an extension method int daysTillEndOfMonth = date.DaysToEndOfMonth(); Console.WriteLine(daysTillEndOfMonth); } } public static class DateUtilities { public static int DaysToEndOfMonth(this DateTime date) { return DateTime.DaysInMonth(date.Year, date.Month) - date.Day; } }

Compiler trick.  Makes the syntax nice. Extension method needs to be in the same namespace.

using System; using System.Collections.Generic; using Extensions; namespace Grades { class Program { static void Main() { // Can hide anything behind IEnumerable eg a database // doesn't define interesting methods.. so MS added extension methods IEnumerable<string> cities = new[] { "Ghent", "London", "Las Vegas", "Hyderbad" }; // Take this datasource, and give me all citites that start with L IEnumerable<string> query = cities.StringThatStartsWith("L"); foreach (var city in query) { Console.WriteLine(city); } } } } namespace Extensions { public static class FilterExtensions { // Extension method for IEnumerable<string> // Data source is IEnumerable<string> public static IEnumerable<string> StringThatStartsWith(this IEnumerable<string> input, string start) { foreach (var s in input) { if (s.StartsWith(start)) { // builds an IEnumerable yield return s; } } } } }

Implementing a simple extension method on IEnumerable<string>
This is the way that LINQ operators are defined.
static void Main() { // Can hide anything behind IEnumerable eg a database // doesn't define interesting methods.. so MS added extension methods IEnumerable<string> cities = new[] { "Ghent", "London", "Las Vegas", "Hyderbad" }; // A very generic operator..need to look at lambda expressions. cities.Where() // Take this datasource, and give me all citites that start with L IEnumerable<string> query = cities.StringThatStartsWith("L"); foreach (var city in query) { Console.WriteLine(city); } }

Lambda Expressions

Making more flexible with a delegate.. So can have an IEnumerable<T>

class Program { static void Main() { IEnumerable<string> cities = new[] { "Ghent", "London", "Las Vegas", "Hyderbad" }; // More flexible, as have a Filter method that can take delegates // that point to other things IEnumerable<string> query = cities.Filter(StringTheStartWithL); foreach (var city in query) { Console.WriteLine(city); } } static bool StringTheStartWithL(string s) { return s.StartsWith("L"); } } public static class FilterExtensions { public static IEnumerable<T> Filter<T> (this IEnumerable<T> input, FilterDelegate<T> predicate) { // foreach item in the input, invoke the predicate (method) // if predicate returns true, add to IEnumerable returning foreach (var item in input) { if (predicate(item)) { // builds an IEnumerable yield return item; } } } } public delegate bool FilterDelegate<T>(T item);


A more flexible approach than writing an extension method for each case
// C#2 Anonymous delegate IEnumerable<string> query = cities.Filter(delegate(string item) { return item.StartsWith("L"); });

This does exactly the same – don’t need a named method.  Can inline it.  A delegate calling an anonymous method.

Goes to operator

// Lambda expression.. LHS is signature of the method (takes a string - type inference) // Body returns a bool of item.StartsWith("L") IEnumerable<string> query = cities.Filter(item => item.StartsWith("L")); foreach (var city in query) { Console.WriteLine(city); }

Lambdas are the way to write delegates in C#3 and above

Func

Passing around small snippets of information to express how to perform an operation – very interesting!

Func is a generic type which encapsulates delegates (callable code)

// Delegate that takes an integer as a parameter, and returns a bool //Func<int, bool> Func<int, int> square = x => x * x; // Parameters requied for 0 or 2+ parameters Func<int, int, int> add = (x, y) => x + y; Console.WriteLine(square(3)); Console.WriteLine(add(3,4)); // Action is just like Func with no return value Action<int> write = x => Console.WriteLine(x); write(16);


Great thing about Func is we no longer need to define delegates
public static class FilterExtensions { // By using Func<T,bool> we don't need to define a delegate public static IEnumerable<T> Filter<T> (this IEnumerable<T> input, Func<T,bool> predicate) { // foreach item in the input, invoke the predicate (method) // if predicate returns true, add to IEnumerable returning foreach (var item in input) { if (predicate(item)) { // builds an IEnumerable yield return item; } } } public static IEnumerable<T> Filterx<T> (this IEnumerable<T> input, FilterDelegate<T> predicate) { // foreach item in the input, invoke the predicate (method) // if predicate returns true, add to IEnumerable returning foreach (var item in input) { if (predicate(item)) { // builds an IEnumerable yield return item; } } } } public delegate bool FilterDelegate<T>(T item);

Using the inbuilt extension method which is just like above using a Func<T>
IEnumerable<string> query = cities.Where(city => city.StartsWith("L")) .OrderByDescending(city => city.Length);

Start of Funcs and Expressions.

| | #