char[] vowels = new char[5];
char[] vowels2 = new char[] {'a','e','i','o','u'};
char[] vowels3 = {'a','e','i','o','u'};
for(int i = 0; i < vowels.Length; i++)
{
Console.Write(vowels[i]);
}
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
}
Point p = new Point(4,5);
using System;
class Test // ref modifier
{
static void Foo(ref int p)
{
Console.WriteLine(p);
p = p + 1;
}
static void Main()
{
int x = 8;
Foo(ref x);
Console.WriteLine(x); // x is now 9
}
}
using System;
class Test // out modifier
{
static void Split (string name, out string firstNames, out string lastName)
{
int i = name.LastIndexOf (' ');
firstNames = name.Substring (0, i);
lastName = name.Substring (i + 1);
}
static void Main()
{
string a, b;
Split ("Stevie Ray Vaughan", out a, out b);
Console.WriteLine (a);
Console.WriteLine (b);
}
}
// outputs:
// Stevie Ray
// Vaughan
using System;
class Test // params modifier
{
static int Sum (params int[] ints)
{
int sum = 0;
for (int i = 0; i < ints.Length; i++)
sum += ints[i];
return sum;
}
static void Main()
{
int total = Sum (1, 2, 3, 4);
Console.WriteLine (total);
}
}
using System;
class Test // Optional parameters
{
static string JoinWith(char a, char b, string del = ",")
{
// C# 6 "interpolated string literal
return $"{a}{del}{b}";
}
static void Main()
{
Console.WriteLine( JoinWith('u','v') );
Console.WriteLine( JoinWith('u','v',"___") );
}
}
// outputs:
// u,v
// u___v
using System;
class Test // Named arguments
{
static void Foo(int x, int y)
{
Console.WriteLine(x + ", " + y);
}
static void Main()
{
Foo(x:1, y:2);
Foo(y:4, x:9);
}
}
// outputs:
// 1, 2
// 9, 4
// Expression-bodied function members
public int AddTwo(int a, int b) => a + b;
// Implicitly typed local variables
var i = 5;
var adj = "a superlative";
var arr = new[] {1,2,3};
var expr =
from c in customers
where c.City == "London"
select c;
string s = null;
string s1 = s ?? "something else";
// "Elvis" operator (?:), prevents NullReferenceException
// AKA: Safe navigation operator
System.Text.StringBuilder sb = null;
string s = sb?.ToString();
// equivalent to
string s = (sb == null ? null : sb.ToString());
// short circuits and is safe
x?.y?.z;
System.Text.StringBuilder sb = null;
string s = sb?.ToString() ?? "something else";
string s = null; // just fine
int a = null; // does not compile
int? id = null; // OK
System.Nullable<int> id = null;
// common MVC pattern
public ActionResult Details(int? id)
{
if(id == null) // or !id.HasValue
{
return new HttpStatusCodeResult(400, "Missing user identifier in request");
}
User user = db.Users.Find(id);
// ...
}
int? x = 8;
int? y = 100;
int? z = null; // i.e. System.Nullable<int> z
// operators are lifted from int
// Normal:
x == y
x + y
x < y
// But must worry about effect of null
x == z // False
x + z // null
x < z // False
x > z // False
namespace SomeNameSpaceName
{
class Class1 {}
// other members
}
namespace Outer {
namespace Middle {
namespace Inner {
class Class2{}
}
}
}
using SomeNameSpaceName;
using Outer.Middle.Inner;
// Auto generated code in: file1.cs
namespace MyApp
{
partial class MyClass { public void MyMethod(){} }
// other members
}
// Your code in: file2.cs
namespace MyApp
{
partial class MyClass { public void OtherMember(){} }
}
using System;
public class Wolf : Canine, IEquatable<Wolf>
{
public string Name = "Wolfie";
public string Owner;
public int Legs;
private static int totalCount;
private DateTime birthday;
public Wolf() {}
public Wolf(string name)
{
this.name = name;
}
//...
}
Wolf w1 = new Wolf("Sharp Teeth") { Owner="Me", Legs=4 };
Wolf w2 = new Wolf { Name="Ghost", Owner="John Snow", Legs=4 };
public class Stock
{
decimal maxPrice; // private "backing field"
public decimal MaxPrice
{
get { return maxPrice; }
set { maxPrice = value; }
}
// Automatic property
public decimal CurrentPrice { get; set; }
}
var s = new Stock();
s.MaxPrice = 99.99M;
Console.WriteLine(s.CurrentPrice);
// Read-only property
string symbol; // set in the constructor
public string Symbol
{
get { return symbol; }
}
// Expression-bodied property (also read-only)
public decimal Worth => currentPrice * sharesOwned;
// Initializer
public int Volume { get; set; } = 100;
class Class1
{
~Class1()
{
// release resources?
}
}
public class Asset
{
public string Name;
public virtual decimal Liability => 0;
}
public class Stock : Asset
{
public long SharesOwned;
}
public class House : Asset
{
public decimal Mortgage;
public override decimal Liability => Mortgage;
public override string ToString() { return "A House"; }
}
public class SubClass : BaseClass
{
public SubClass( int x ) : base (x) { }
}
// Can also use base like this (no super)
int a = base.someNum;
// System.Object or object is the base of the object hierarchy
object o = new House();
// C# has boxing and unboxing
int age = 32;
object obj = age;
int myAge = (int)obj;
// Declare a new type
public delegate double BinaryOperator( double a, double b );
// Create methods we want to use
public static double Add( double a, double b ) => a + b;
public static double Sub( double a, double b ) => a - b;
public static double Div( double a, double b ) => a / b;
public static double Mul( double a, double b ) => a * b;
// Create an instance of the delegate type
BinaryOperator bop = Sub;
// Use it
Console.WriteLine( "7 - 9.3 = " + bop(7,9.3) );
// Expression Lambdas
// (input parameters) => expression
x => x * x
(x,y) => x == y
(int x, string s) => s.Length > x
// Statement Lambdas
// (input parameters) => { statement1; statement2; statement3; }
() => {Console.WriteLine("Hello Lambda!");}
(x,y) => { return x == y; } // weird way to write that!
// C# 3.0 defined
namespace System
{
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
}
Func<double, double, double> sum = (x,y) => x + y;
public static IEnumerable<U> Map(Func<T, U> fn, IEnumerable<T> list)
{
//apply fn to list and return resulting new list
}
var output = Map( x => x * x, nums );
using
statement for extension class in order to use it (i.e. using System.Linq;
for LINQ operators)this
modifier as first parameter// "Add" to string class
public static class StringHelper
{
public static bool IsCapitalized (this string s)
{
if (string.IsNullOrEmpty(s))
return false;
return char.IsUpper (s[0]);
}
}
// Call it as a built-in method
"Perth".IsCapitalized();
// or as a static method
StringHelper.IsCapitalized("Perth");
// How it's translated:
arg0.Method(arg1, arg2, ...); // Extension method call
StaticClass.Method(arg0, arg1, arg2, ...); // Static method call
// Map example from previous slide
// written as an extension method
Func<double, double, double> sum = (x,y) => x + y;
public static IEnumerable<U> Map(this IEnumerable<T> list, Func<T, U> fn)
{
//apply fn to list and return resulting new list
}
var output = nums.Map( x => x * x );
Look at some definitions in IEnumerable<T>
int[] ints = { 10, 45, 15, 39, 21, 26 };
var result = ints.OrderBy(g => g).Take(4).Average();
// Versus
var result = Average(Take(OrderBy(ints, g=>g),4));
object
var
keyword to create new objects of this type.Equals()
that compares members for equalityvar obj = new {Name = "Jane", Age = 28, CellNumber = "555-555-1111" };
// or
var obj2 = new {
Store = "ShoesForLess",
Categories = new String[]{"Running","Leisure","Dress","Sandals"},
Date = DateTime.Now
}
Console.WriteLine(obj2.Store);
Useful in LINQ select queries
var categories = db.ProductCategories
.OrderBy( pc => pc.Name )
.Select( pc => new { Name = pc.Name,
Id = pc.ProductCategoryID } );
“Attributes are an extensible mechanism for adding custom information to code elements (assemblies, types, members, return values, parameters and generic type parameters).”
i.e. decorating code elements with metadata
Used extensively in ASP.NET MVC
// For specifying SQL attributes
public partial class SomeClass
{
[Key]
[StringLength(4)]
public string GuID { get; set; }
[Required, StringLength(64)]
public string ModelName { get; set; }
[Required]
[Phone]
[Display(Name = "Phone Number")]
public string Number { get; set; }
}
Used extensively in ASP.NET MVC
// For specifying behavior in controller action methods
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult Apply(MemberInfoViewModel newMember)
{
if (ModelState.IsValid)
{
//...
return RedirectToAction("Index", "Manage", new { success = true });
}
return View(newMember);
}
Adding an attribute causes an instance of the attribute class to be created and attached to the element. At runtime, code can use reflection to inquire about available attribute objects and use them accordingly.
// Creating an attribute to manage HTTP's Basic Authentication
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication
public class BasicAuthenticationAttribute : ActionFilterAttribute
{
public string BasicRealm { get; set; }
protected string Username { get; set; }
protected string Password { get; set; }
public BasicAuthenticationAttribute(string username)
{
//...
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//...
}
}
Built-in data structures of both generic and non-generic types
Yup, the usual:
using System;
using System.Collections;
public class SamplesArrayList
{
public static void Main()
{
// Creates and initializes a new ArrayList.
ArrayList myAL = new ArrayList();
myAL.Add("Hello");
myAL.Add("World");
myAL.Add("!");
// Displays the properties and values of the ArrayList.
Console.WriteLine( "myAL" );
Console.WriteLine( " Count: {0}", myAL.Count );
Console.WriteLine( " Capacity: {0}", myAL.Capacity );
Console.Write( " Values:" );
PrintValues( myAL );
}
public static void PrintValues( IEnumerable myList )
{
foreach ( object obj in myList )
Console.Write( " {0}", obj );
Console.WriteLine();
}
}
And in generic form
// using System.Collections.Generic
List<string> dinosaurs = new List<string>();
Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity);
dinosaurs.Add("Tyrannosaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("Mamenchisaurus");
dinosaurs.Add("Deinonychus");
dinosaurs.Add("Compsognathus");
Console.WriteLine();
foreach(string dinosaur in dinosaurs)
{
Console.WriteLine(dinosaur);
}
We frequently use objects of these types:
and should look closely at these interfaces
IEnumerable<T>
and/or IQueryable
System.Linq
and System.Linq.Expressions
string[] names = { "Tom", "Dick", "Harry" };
IEnumerable<string> out = names.Where(n => n.Length >= 4);
foreach (string name in out)
Console.WriteLine (name);
// Dick
// Harry
Using Fluent Syntax
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
IEnumerable<string> out = names.Where(n => n.Contains("a"))
.OrderBy(n => n.Length)
.Select(n => n.ToUpper());
foreach (string name in out)
Console.WriteLine (name);
// JAY
// MARY
// HARRY
Classification | Operators |
---|---|
Filtering | Where, OfType |
Sorting | OrderBy, OrderByDescending, ThenBy, ThenByDescending, Reverse |
Grouping | GroupBy, ToLookup |
Join | GroupJoin, Join |
Projection | Select, SelectMany |
Aggregation | Aggregate, Average, Count, LongCount, Max, Min, Sum |
Classification | Operators |
---|---|
Quantifiers | All, Any, Contains |
Elements | ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault |
Set | Distinct, Except, Intersect, Union |
Partitioning | Skip, SkipWhile, Take, TakeWhile |
Concatenation | Concat |
Equality | SequenceEqual |
Generation | DefaultEmpty, Empty, Range, Repeat |
Conversion | AsEnumerable, AsQueryable, Cast, ToArray, ToDictionary, ToList |
// Pagination
public ViewResult List(int page = 1)
{
return View(db.Products.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize));
}
http://www.example.com/somepath/hello.php
<!-- hello.php -->
<html>
<head>
<title>Hello PHP!</title>
</head>
<body>
<?php
echo "<h1>Hello World!</h1>";
?>
</body>
</html>
http://www.oregon.gov/ODOT/Pages/index.aspx
http://www.thingiverse.com/thing:776259
http://www.autotrader.com/cars-for-sale/Used+Cars/Porsche/Cayman/Albany+OR-97321?endYear=2008&firstRecord=0&listingType=used&listingTypes=used&makeCode1=POR&
mmt=%5BPOR%5BCAYMAN%5B%5D%5D%5B%5D%5D&modelCode1=CAYMAN&searchRadius=25&
showcaseOwnerId=68403481&startYear=2000&transmissionCode=MAN&
transmissionCodes=MAN&Log=0&showcaseListingId=438099248&
captureSearch=true&fromSIP=C07B36E73BF24F8EDCE2D641DB137905&
showToolbar=true
Order of events
Entity Framework (EF) is an object-relational mapper that enables .NET developers to work with relational data using domain-specific objects. It eliminates the need for most of the data-access code that developers usually need to write.
Within a database-backed model class:
See Pro ASP.NET MVC 5 Book, Ch. 15
Technically separate from MVC.
Is used in Web API, Forms, etc.
Very configurable.
// in Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
//in App_Start\RouteConfig.cs
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
controller = "Home",
action = "Index",
id = UrlParameter.Optional }
);
}
}
{controller}/{action}/{id}
Incoming URL | Maps To |
---|---|
~/ | Controller: Home Action: Index id: |
~/User | Controller: User Action: Index id: |
{controller}/{action}/{id}
Incoming URL | Maps To |
---|---|
~/User/Details | Controller: User Action: Details id: |
~/User/Details/53 | Controller: User Action: Details id: 53 |
{controller}/{action}/{id}
Incoming URL | Maps To |
---|---|
~/User/Details/Julie | Controller: User Action: Details id: Julie |
~/User/Details/Julie/Add | No match, too many segments |
{controller}/{action}/{id}
defaults
Incoming URL | Maps To |
---|---|
~/ | No match, not enough segments |
~/Home | No match, not enough segments |
~/Home/Contacts | No match, not enough segments |
~/Home/Contacts/3 | Controller: Home Action: Contacts id: 3 |
RegisterRoutes
controller
and action
"variables" have special meaning in an MVC app, otherwise can make up new variables"^H.*"
routes.MapRoute(
name: "API Routes",
url: "api/{controller}/{action}/{version}",
defaults: new {
controller = "ExternalAPI",
action = "Handler",
version = "v2" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
controller = "Home",
action = "Index",
id = UrlParameter.Optional }
);
Incoming URL | Maps To |
---|---|
~/ | Controller: Home Action: Index id: |
~/api | Controller: ExternalAPI Action: Handler version: v2 |
~/api/Requests | Controller: Requests Action: Handler version: v2 |
~/apis | Controller: Apis Action: Index id: |
~/2011/ (all posts from 2011) ~/2011/11/ (all posts from November 2011) ~/2011/11/07 (all posts from November 7th 2011) ~/2011/11/07/exact-post-title ~/exact-post-title ~/about ~/archive ~/tag/whatever-tag
public ActionResult Details()
{
object id = RouteData.Values["id"];
return View();
}
// or better yet
public ActionResult Details(int? id)
{
return View();
}
// parameter and segment variable must match exactly, i.e. cannot be
public ActionResult Details(int? value)
public ActionResult Details(int? yyyy, string mm, string dd, string title) {}
public ActionResult ByDay(int? yyyy, string mm, string dd) {}
// or
public ActionResult ByDay(int yyyy, int mm, int dd)
// if you can be sure single digit numbers like 04 are parsed correctly
// and that no-one makes these segment variables optional in routing table
// at a future time
See Pro ASP.NET MVC 5 Book, Ch. 17
// ControllersAndActionMethods project
public class BasicController : IController
{
public void Execute(RequestContext requestContext)
{
}
}
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
}
public ActionResult Gimme(int id)
// Search in order:
Request.Form["id"]
RouteData.Values["id"]
Request.QueryString["id"]
Request.Files["id"]
IModelBinder
will try to convert to the type required by the parameterModelState
DataAnnotations
are used in the model, will set validation errors in ModelState.Values
public ActionResult GimmeAPerson(Models.Person person)
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public Address HomeAddress { get; set; }
public bool IsApproved { get; set; }
}
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
Include or exclude values from binding and from validation
public ActionResult Update([Bind(Exclude = "PersonID")] Person person)
// or e.g. in the Entity Framework scaffolded code from HW 6
public ActionResult Create([Bind(Include = "PersonID,FullName,PreferredName,SearchName,IsPermittedToLogon,LogonName,IsExternalLogonProvider,HashedPassword,IsSystemUser,IsEmployee,IsSalesperson,UserPreferences,PhoneNumber,FaxNumber,EmailAddress,Photo,CustomFields,OtherLanguages,LastEditedBy,ValidFrom,ValidTo")] Person person)
ModelState
ActionResult
to be created, including
// The default. Search for "Index" in
// ~/Views/ControllerName/"ViewName".aspx
// ~/Views/ControllerName/"ViewName".ascx
// ~/Views/Shared/"Viewname".aspx
// ~/Views/Shared/"Viewname".ascx
// ~/Views/ControllerName/"ViewName".cshtml
// ~/Views/ControllerName/"ViewName".vbhtml
// ~/Views/Shared/"Viewname".cshtml
// ~/Views/Shared/"Viewname".vbhtml
public ActionResult Index() {return View();}
// Or can specify "ViewName"
return View("HomePage");
// Or full path
return View("~/Views/Other/Index.cshtml");
public ActionResult Index()
{
WebRequest request = WebRequest.Create(@"https://example.com/resource");
WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
var data = ProcessData(responseFromServer);
return View(data);
}
public async Task<ActionResult> Index()
{
WebRequest request = WebRequest.Create(@"https://example.com/resource");
WebResponse response = await request.GetResponseAsync();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
var data = ProcessData(responseFromServer);
return View(data);
}
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
Source: C# 6.0 in a Nutshell, Ch. 14
async
and await
keywordsNo, I didn't make this up. It's from Asynchronous programming [in .NET]
"Javascript is a single-threaded non-blocking asynchronous concurrent language"
Philip Roberts: What the heck is the event loop anyway? JSConf EU 2014
Loupe
//https://nodejs.org/en/docs/guides/getting-started-guide/
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
//https://expressjs.com/en/starter/hello-world.html
const express = require('express')
const app = express()
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(3000, () => console.log('Example app listening on port 3000!'))