dynamic c#
DESCRIPTION
Dynamic C#TRANSCRIPT
by @AntyaDev
DYNAMIC C#
STATIC VS DYNAMIC
The many faces of “dynamic”
Generate code at runtime
Changing types at runtime
No typesat all
Simplified deployment
• Trend on non-schematized data
• Remember WSDL, SOAP, XSD?
• How about REST, JSON?
• The next browser war
• JavaScript on the web
• Optimized scripting engines
• Towards metaprogramming?
• Ruby community
• Code as data
IT’S A DYNAMIC WORLD
DynamicLanguages
Simple and succinct
Implicitly typed
Meta-programming
No compilation
StaticLanguages
Robust
Performant
Intelligent tools
Better scaling
STATIC VS DYNAMIC
DLR Hero• Jim Hugunin
Co-designer ASpectJ
Jython implementation• Python on the JVM
IronRuby implementation• Python on the .NET
DLR Hero• John Lam
RubyCLRbridge between the Ruby interpreter and the CLR
IronRubyRuby on the .NET
DLR Hero
Martin Maly
Common Language Runtime
Dynamic Language Runtime
C# compiler teamChris Burrow, Sam Ng
Action Python Ruby C# VB.NET
GetMember x.Foo x.Foo x.Foo x.Foo
SetMember x.Foo = y x.Foo = y x.Foo = y x.Foo = y
DeleteMember del d.Foo x.send :remove_instance_variable :@foo No syntax No syntax
UnaryOperation -x -x -x -x
BinaryOperation x + y x + y x + y x + y
Convert No syntax No syntax (Foo)x CType(x,Foo)
InvokeMember x.Foo(a,b) x.Foo(a,b) x.Foo(a,b) x.Foo(a,b)
Invoke x(a,b) x.call(a,b) x(a,b) x(a,b)
CreateInstance X(a,b) X.new(a,b) No syntax No syntax
GetIndex x[a,b] x[a,b] x[a,b] x(a,b)
SetIndex x[a,b] = y x[a,b] = y x[a,b] = y X(a,b) = y
DeleteIndex del x[a,b] No syntax No syntax No syntax
Common actions
IDynamicMetaObjectProvider
public interface IDynamicMetaObjectProvider{ DynamicMetaObject GetMetaObject(Expression parameter);}
DynamicMetaObject
public class DynamicMetaObject{ public BindingRestrictions Restrictions { get; }
public Expression Expression { get; }
public bool HasValue { get; }
public object Value { get; }
public Type RuntimeType { get; }
public virtual DynamicMetaObject BindGetMember(GetMemberBinder b); public virtual DynamicMetaObject BindSetMember(SetMemberBinder b, DynamicMetaObject value); public virtual DynamicMetaObject BindDeleteMember(DeleteMemberBinder b);
// Other bind operations…}
System.Dynamic.DynamicObjectpublic class DynamicObject : IDynamicMetaObjectProvider
{
public virtual bool TryBinaryOperation(BinaryOperationBinder binder, object
arg, out object result);
public virtual bool TryConvert(ConvertBinder binder, out object result);
public virtual bool TryCreateInstance(CreateInstanceBinder binder, object[]
args, out object result);
public virtual bool TryGetIndex(GetIndexBinder binder, object[] indexes, out
object result);
public virtual bool TryGetMember(GetMemberBinder binder, out object result);
public virtual bool TryInvoke(InvokeBinder binder, object[] args, out object
result);
public virtual bool TryInvokeMember(InvokeMemberBinder binder, object[] args,
out object result);
public virtual bool TrySetIndex(SetIndexBinder binder, object[] indexes,
object value);
public virtual bool TrySetMember(SetMemberBinder binder, object value);
}
PythonBinder
RubyBinder
COMBinder
JavaScriptBinder
ObjectBinder
DYNAMIC LANGUAGE RUNTIME (DLR)
Dynamic Language RuntimeDLR Trees Dynamic Dispatch Call Site Caching
IronPython IronRuby C# VB.NET Others…
CALL SITES
• Old Idea: Polymorphic Inline Cache• Implemented with delegates and generics• No changes in CLR runtime engine (today)
• Major Addition: Multiple languages on CLR• Interop for sharing objects across languages• Customization to work for each language• Customization for library writers
• System.Runtime.CompilerServices
CLR
ExeCompile Run
Bind call
Expression Tree
Dynamic CallDelegate
DLR
Cache
COM Binder
IronPython Binder
C# Runtime Binder
…
HOW DYNAMIC WORKS
CALLSITE<T>
static CallSite<Func<CallSite, object, int, bool>> _site = …;
if (_site.Target(_site, x, 0)) { … }
if (x == 0) { … }
static bool _0(Site site, object x, int y) { return site.Update(site, x, y); //tailcall}
As strongly typed as possible
Cache is learning
CALLSITE<T>
static CallSite<Func<CallSite, object, int, bool>> _site = …;
if (_site.Target(_site, x, 0)) { … }
if (x == 0) { … }
static bool _2(Site site, object x, int y) { if (x is int) { return (int)x == y; } else if (x is BigInteger) { return BigInteger.op_Equality((BigInteger)x, y); } else { return site.Update(site, x, y); //tailcall }}
DynamicMetaObject
public class DynamicMetaObject{ public BindingRestrictions Restrictions { get; }
public Expression Expression { get; }
public bool HasValue { get; }
public object Value { get; }
public Type RuntimeType { get; }
public virtual DynamicMetaObject BindGetMember(GetMemberBinder b); public virtual DynamicMetaObject BindSetMember(SetMemberBinder b, DynamicMetaObject value); public virtual DynamicMetaObject BindDeleteMember(DeleteMemberBinder b);
// Other bind operations…}
Show me Dynamic C#
Ruby’s Markup Builder is an example of what can be achieved with
method missing
b = Builder::XmlMarkup.newhtml = b.html { b.head { b.title "XML Builder Test" } b.body { b.h1 "Title of Page“ b.p "Sample paragraph text“ b.p "Sample paragraph text“ }}
<head> <title>XML Builder Test</title> - <body> <h1>Title of Page</h1> <p>Sample paragraph text</p> <p>Sample paragraph text</p> </body></head>
class User < ActiveRecord::Base; end
users = User.find_all_by_state("TX")
user = User.find_or_create_by_email("[email protected]")
Send Message
Receive Message
by @AntyaDev
OakFrictionless development for ASP.NET MVC single page web apps. Prototypical and dynamic capabilities brought to C#.
STATIC TYPING WHERE POSSIBLE, DYNAMIC TYPING WHEN NEEDED
LINKS
• KingAOP: https://github.com/AntyaDev/KingAOP• Simple.Data: https://github.com/markrendle/Simple.Data• Massive: https://github.com/robconery/massive• CarealBox: https://github.com/JonCanning/CerealBox• Oak: http://amirrajan.github.io/Oak/
https://twitter.com/AntyaDev
https://github.com/AntyaDev
http://antyadev.blogspot.com/
THANK YOU!