anything you can do i can do betterlaser.inf.ethz.ch/2012/slides/meijer/lecture2.pdf · the...

33
Anything You Can Do I Can Do Better

Upload: others

Post on 13-Jun-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Anything You Can Do I Can Do Better

Page 2: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Algebraic Data Types

Dynamic type

Pattern Matching

Page 3: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Constructors

Page 4: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Extension Methods

Page 5: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Play

Page 6: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

GATDs

Page 7: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic
Page 8: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic
Page 9: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic
Page 10: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic
Page 11: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

A Simple Concrete Example

Page 12: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic
Page 13: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic
Page 14: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

To keep self heating below 0.1°C, SHT7x should not be active for more than 10% of the time – e.g. maximum one measurement per second at 12bit accuracy shall be made.

public class Thermometer {

public static event Action<double> Temperature; const int VendorId = 0x0C70; const int ProductId = 0x0750; static readonly byte[] ReadTemperature = new byte[]{0x0, 0x0}; static readonly HidDevice _device; static Thermometer() { _device = HidDevices.Enumerate(VendorId, ProductId).First(); _device.OpenDevice(); Loop(); } static void Loop() { _device.Write(ReadTemperature); _device.ReadReport(report => { var listeners = Temperature; if(listeners != null) { var data = report.Data;

var temperature = -45+(0.01*BitConverter.ToInt16( new []{data[1], data[0]}, 0)); listeners(temperature); } Thread.Sleep(1000); Loop(); });}}

Page 15: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

27.5, 27.44, 27.39, 27.72, 28.35, 28.82, 29.14, 29.42, 29.64, 29.83, 29.99, 30.12, 30.24, 30.36, 30.45, 30.54, 30.6, 30.68, 30.72, 30.77, 30.82, 30.86, 30.88, 30.91, 30.93, 30.97, 30.99, 31.03, 31.02, 31.04, 31.05, 30.78, 30.58, 30.39, 30.22, 30.08, 29.9, 29.76, 29.64, 29.52, 29.41, 29.32, 29.24, 29.17, 29.07, 28.96, 28.88, 28.82, 28.72

Thermometer.Temperature += t => Console.Write("{0}, ", t);

Page 16: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Time

Temp

alert

safe

How do we convert stream of temperature event notifications to alerts? How do we react to alerts, e.g. send SMS or email?

Page 17: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Twilio

Page 18: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

curl -X POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/SMS/Messages \ --data-urlencode "To=+1…" \ --data-urlencode "From=+1…" \ --data-urlencode "Body="Hello world!" \ -u {AccountSid}:{AuthToken}

Page 19: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic
Page 20: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

public class BasicAuthenticationHeaderValue : AuthenticationHeaderValue { public BasicAuthenticationHeaderValue(string username, string password): base("Basic",Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes( string.Format("{0}:{1}", username, password)))){} } public class SMS {

const string Twilio = @"https://api.twilio.com/ 2010-0401/Accounts/{0}/SMS/Messages.json"; readonly string AccountSid; readonly string AuthToken; public SMS(string accountSid, string authToken) { AccountSid = accountSid; AuthToken = authToken; } public Task<HttpResponseMessage> Send(string @from, string @to, string @body) { var client = new HttpClient{ DefaultRequestHeaders = { Authorization = new BasicAuthenticationHeaderValue(AccountSid, AuthToken) }}; var msg = new FormUrlEncodedContent(new NameValuePairs{ { "From", @from}, { "To", @to}, { "Body", @body } });

return client.PostAsync(string.Format(Twilio, AccountSid), msg); } } public class NameValuePairs : Dictionary<string, string>{}

Page 21: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

{"sid":"…" ,"date_created":"Wed, 29 Aug 2012 13:30:42 +0000" ,"date_updated":"Wed, 29 Aug 2012 13:30:42 +0000" ,"date_sent":null ,"account_sid":"…" ,"to":"+1…","from":"+1…" ,"body":"3:30:43 PM" ,"status":"queued" ,"direction":"outbound-api" ,"api_version":"2010-04-01" ,"price":null ,"uri":"\/2010-04-01\/Accounts\/…\/SMS\/Messages\/….json" } Please, no more

boilerplate mapping code!

Response

Page 22: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

var s = @"{ ,""date_created"":""Wed, 29 Aug 2012 13:30:42 +0000"" }"; var json = System.Json.JsonValue.Parse(s).Dump(); var created= json["date_created"]; ((DateTime)created).Dump(); dynamic jsond = json; ((DateTime)jsond.date_created).Dump();

Page 23: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Static Typing Where Possible Dynamic Typing Where Necessary

dynamic x = …;

Static type to indicate dynamic typing ;-)

Page 24: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Visual Basic had this features

forever

Page 25: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

Dynamic Resolution Rules •Try to resolve statically (.ToString(), .Equals()). • If the value implements the interface IDynamicMetaObjectProvider, it is a so-called dynamic object, which means that it will itself be asked to bind and perform the operation. • If the value is a COM object, the operation is dispatched

dynamically through COM IDispatch. • If the value is a standard .NET object, and the operation

will be dispatched using reflection on its type and a C# “runtime binder”.

Page 26: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

dynamic d = … instance of MyDynamicObject …; d.M(7); // calling methods // getting and settings fields and properties d.f = d.P; // getting and setting through indexers d["one"] = d["two"]; int i = d + 3; // calling operators string s = d(5,7); // invoking as a delegate var c = new C(d); // calling a constructor

Page 27: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

class JsonValue : IDynamicMetaObjectProvider , … { } class DynamicObject : IDynamicMetaObjectProvider { }

The DynamicObject class enables you to define which operations can be performed on dynamic objects and how to perform those operations. For example, you can define what happens when you try to get or set an object property, call a method, or perform standard mathematical operations such as addition and multiplication.

Page 28: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

class MyDynamicObject : DynamicObject { override IEnumerable<string> GetDynamicMemberNames(){} override DynamicMetaObject GetMetaObject(Expression parameter){} override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result){} override bool TryConvert(ConvertBinder binder, out object result){} override bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result){} override bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes){} override bool TryDeleteMember(DeleteMemberBinder binder){} override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result){} override bool TryGetMember(GetMemberBinder binder, out object result){} override bool TryInvoke(InvokeBinder binder, object[] args, out object result){} override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result){} override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value){} override bool TrySetMember(SetMemberBinder binder, object value){} override bool TryUnaryOperation(UnaryOperationBinder binder, out object result){} }

Page 29: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

var b = new B() as A; F(b); // A F(b as dynamic); // B void F(A a) { Console.WriteLine("A"); } void F(B a) { Console.WriteLine("B"); } class A {} class B : A {}

“multi method”

Page 30: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

b.G(); // Hi! (b as dynamic).G(); // throws static class Extensions { public static void G(this A a) { Console.WriteLine("Hi!"); } public static void G(this B a) { Console.WriteLine("There!"); } } Compile-time

hack

Page 31: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

void Main() { var bankAccounts = new [] { new { ID = 345678, Balance = 541.27 } , new { ID = 1230221, Balance = -127.44 } }; DisplayInExcel(bankAccounts); CreateIconInWordDoc(); }

Office/COM interop

Page 32: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

static void DisplayInExcel(IEnumerable<dynamic> accounts) { var excelApp = new Excel.Application { Visible = true , Workbooks = { XlWBATemplate.xlWBATWorksheet } } as dynamic; var workSheet = excelApp.ActiveSheet; workSheet.Cells[1, "A"] = "ID Number"; workSheet.Cells[1, "B"] = "Current Balance"; foreach (var _ in accounts.Select((account,i) => new { account, row = i+2})) { workSheet.Cells[_.row, "A"] = _.account.ID; workSheet.Cells[_.row, "B"] = _.account.Balance; } workSheet.Columns[1].AutoFit(); workSheet.Columns[2].AutoFit(); // Put the spreadsheet contents on the clipboard. workSheet.Range["A1:B3"].Copy(); }

Page 33: Anything You Can Do I Can Do Betterlaser.inf.ethz.ch/2012/slides/Meijer/Lecture2.pdf · The DynamicObject class enables you to define which operations can be performed on dynamic

static void CreateIconInWordDoc() { var wordApp = new Word.Application{ Visible = true }; wordApp.Documents.Add(DocumentType: WdNewDocumentType.wdNewBlankDocument); // 7 optional parameters wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true); }