Required SlideIntroduction to C# 4.0 and DynamicBy: Gieno Miaogieno.miao@live.com
The Evolution of C#C# 4.0Dynamic ProgrammingC# 3.0Language Integrated QueryRuby On Rails 2.0C# 2.0GenericsJava EE 5, Ruby On Rails 1.0C# 1.0Managed CodeMono announced, J2SE 1.4
C# 4.0 Language InnovationsDynamically Typed ObjectsOptional and Named ParametersImproved COM InteroperabilityCo- and Contra-variance
Why Dynamic?There is a lot of interest in accessing the highly dynamic object model of HTML DOMCOM is heavily used and inter op code could be easier to read and writeDynamic languages are becoming increasingly popular     We need unified way to work with all of the above
.NET Dynamic Programming ArchitectureIronPythonIronRubyC#VB.NETOthers…Dynamic Language RuntimeExpression TreesDynamic DispatchCall Site CachingPythonBinderRubyBinderCOMBinderJavaScriptBinderObjectBinder
Dynamically Typed ObjectsCalculator calc = GetCalculator();int sum = calc.Add(10, 20);.NET objectobject calc = GetCalculator();TypecalcType = calc.GetType();object res = calcType.InvokeMember("Add",BindingFlags.InvokeMethod, null,newobject[] { 10, 20 });int sum = Convert.ToInt32(res);Dynamic Language objectScriptObject calc = GetCalculator();object res = calc.Invoke("Add", 10, 20);int sum = Convert.ToInt32(res);Statically typed to be dynamicdynamic calc = GetCalculator();int sum = calc.Add(10, 20);Dynamic method invocationDynamic conversion
dynamic calc = GetCalculator();int sum = calc.Add(10, 20);Under the coverdynamic is a new type only in the compilerEncoded in IL as object + dynamic attributeOperations on a dynamic variable become CallSites, objects “interpreted” by the DLRmember selection deferred to run-timecache the result of the bindingsthe return type of a dynamic operation is dynamicSupport all types of operations on dynamicmethod call, property access, indexer access, operators, conversions
dynamici = 3;Math.Abs(i);Under the coverFor binding calls to .NET types there is a runtime C# binderDoes overload resolution using runtime types for dynamic argumentsOverload resolution changed to accommodate dynamic method callsDynamic arguments are treated as wildcards for overload resolution
Under the coverWhen dose the compiler dispatch dynamically?if the receiver of the call is dynamic ORif any of the arguments to the call are typed dynamicWe can dynamically dispatch to static methods 
Under the coverdynamic d = newDynamicObject();d.Foo();You can now write your own object that does dynamic dispatchjust implement IDynamicObjectThe C# runtime binder can function as a fallback for calls to dynamic objectsif your object is “hybrid” and some of the methods are dynamically dispatched and some are regular methodsthe C# semantics will be applied if the Object cannot itself resolve a call
IDynamicObjectpublicabstractclassDynamicObject : IDynamicObject{publicvirtualobjectGetMember(GetMemberBinder info);publicvirtualobjectSetMember(SetMemberBinder info, object value);publicvirtualobjectDeleteMember(DeleteMemberBinder info); publicvirtualobjectUnaryOperation(UnaryOperationBinder info);publicvirtualobjectBinaryOperation(BinaryOperationBinder info, objectarg);publicvirtualobject Convert(ConvertBinder info); publicvirtualobject Invoke(InvokeBinder info, object[] args);publicvirtualobjectInvokeMember(InvokeMemberBinder info, object[] args);publicvirtualobjectCreateInstance(CreateInstanceBinder info, object[] args); publicvirtualobjectGetIndex(GetIndexBinder info, object[] indices);publicvirtualobjectSetIndex(SetIndexBinder info, object[] indices, object value);publicvirtualobjectDeleteIndex(DeleteIndexBinder info, object[] indices); publicMetaObjectIDynamicObject.GetMetaObject();}
Improved COM interoperabilityAutomatic object -> dynamic mappingOptional and named parametersOptional “ref” modifierInterop type embedding (“No PIA”)Indexed properties
object -> dynamic mappingWe need to cast((Excel.Range)xl.Cells[1,1]).Value2 = “ID”;xl.Cells[1,1].Value2 = “ID”;When the return type of a COM call is object you are forced to cast to a known typeMaking the code harder to understandIf the return type is dynamic, you can continue to “dot” on the return typeIf you typed something wrong the compiler won’t tell you
Optional and named parametersxlChart.ChartWizard(cellRange.CurrentRegion,    Constants.xl3DBar, Type.Missing, Excel.XlRowCol.xlColumns,   1, 2, false, xlSheet.Name, Type.Missing, Type.Missing, Type.Missing);Non-optional must be specifiedxlChart.ChartWizard(cellRange.CurrentRegion, Constants.xl3DBar, PlotBy: Excel.XlRowCol.xlColumns,SeriesLabels: 2, CategoryLabels: 1, HasLegend: false,    Title: xlSheet.Name);Arguments evaluated in order writtenNamed arguments can appear in any order
Optional and named parametersOptional parameterspublicStreamReaderOpenTextFile(    string path,    Encodingencoding,booldetectEncoding,intbufferSize);publicStreamReaderOpenTextFile(    string path,    Encodingencoding = null,booldetectEncoding = true,intbufferSize = 1024);Named argumentOpenTextFile("foo.txt”);OpenTextFile("foo.txt", Encoding.UTF8, bufferSize: 4096);
Optional “ref” modifierobjectfileName = "Test.docx";object missing  = System.Reflection.Missing.Value;doc.SaveAs(reffileName,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing);doc.SaveAs("Test.docx");
Under the coverThe default value for a parameter is encoded with DefaultParameterValue attributeThe compiler inserts that value if a value is not specified for that parameterIf a default value is not specified we will use default (type)For COM the compiler will pass in Type.MissingThe compiler will rearrange the specified named parameters and then apply overload resolution
Under the coverYou can override methods that declare optional parametersThe value of the parameter comes from the static type you used to call the methodYou can rename a parameter in an overrideThe compiler will use the name found in the static type you used to call the method“Omit ref” only works for COM objectsThe compiler creates a variable to store the value you specified and passes the created variable “by ref” to COM
Co- and Contra-variance.NET arrays are co-variantstring[] strings = GetStringArray();Process(strings);…but not safelyco-variantvoid Process(object[] objects) { … }void Process(object[] objects) {   objects[0] = "Hello";       // Ok   objects[1] = newButton();  // Exception!}Until now, C# generics have been invariantList<string> strings = GetStringList();Process(strings);C# 4.0 supports safe co- and contra-variancevoid Process(IEnumerable<object> objects) { … }void Process(IEnumerable<object> objects) {// IEnumerable<T> is read-only and// therefore safely co-variant}
Safe Co- and Contra-variancepublicinterfaceIEnumerable<T>{IEnumerator<T> GetEnumerator();}publicinterfaceIEnumerable<out T>{IEnumerator<T> GetEnumerator();}out= Co-variantOutput positions onlyCan be treated asless derivedpublicinterfaceIEnumerator<T>{   T Current { get; }boolMoveNext();}publicinterfaceIEnumerator<out T>{   T Current { get; }boolMoveNext();}IEnumerable<string> strings = GetStrings();IEnumerable<object> objects = strings;in= Contra-variantInput positions onlypublicinterfaceIComparer<T>{int Compare(T x, T y);}publicinterfaceIComparer<in T>{int Compare(T x, T y);}Can be treated asmore derivedIComparer<object> objComp = GetComparer();IComparer<string> strComp = objComp;
Variance in C# 4.0supported for interface and delegate typesstatically checked definition site variancevalue types are always invariantIEnumerable<int> is not IEnumerable<object>similar to existing rules for arraysref and out parameters need invariant type
SummaryWe have a new type called dynamicCalls that involve variables of type dynamic are treated differently by compilerWe package extra information about the callCalls can be: method calls, property access, indexer call, operator callThere is a C# runtime binder to interpret the information (at runtime)It uses the runtime type for all dynamic argumentsIt uses the compile time type for all other arguments
How dynamic worksCLRExpression TreeCOM BinderExeIronPython BinderCompileRunBind callDynamic CallDelegateDLRC# Runtime BinderCache…
ReviewWhat is the dynamic type?There is no dynamic type . There is only object.What operations are supported?A variable of type dynamic is assumed to support any kind of operation (method call, property access, indexer call and operator call)How is the information about the call stored?Using CallSites objects the compiler packages data about the call
What does a CallSite contain?Information about the call being madeWhat type of call (method call, property access, etc)The name of the memberThe context of the callThe type arguments for the callInformation about the parameter and return typesIs it a constant? Is it passed by-ref, etc.
Dynamic FAQWhen do you go dynamic?When the target of the call OR any of the call arguments are dynamicWhat is the return type of a dynamic call?It is dynamic in most caseWhat about conversions and constructors?They are dispatched at runtime, but their return type is known at compile time
Dynamic FAQWhat about private methods?Information about the context of call is embedded in the CallSite allowing the Binder to “do the right thing”Calling a method off a non-dynamic target with dynamic argumentsIt works as expected We embed the type of all the receiver in the CallSiteCan dynamic “cross” assembly boundaries?Yes, we decorate any dynamic parameter or return type with a DynamicAttributeIt works for generic types constructed with dynamic as well 
Dynamic FAQCan I use named and optional with dynamic?Yes And also Co & Contra varianceWhere can’t I use dynamic?Lambda expressionsLINQCan’t use dynamic with method groupsThrow or catch statements
 Quiz!classBase {    publicvirtualvoid Foo(int x = 4, int y = 5) {        Console.WriteLine("x:{0}, y:{1}", x, y);    }}classDerived : Base {    publicoverridevoid Foo(int y = 4, int x = 5) {        Console.WriteLine("x:{0}, y:{1}", x, y);    }}classProgram {    staticvoid Main(string[] args) {        Base b = newDerived();        b.Foo(x: 4, y: 5);    }}Output:x:4, y:5x:5, y:4x:4, y:4x:5, y:5None of the aboveOutput:x:4, y:5x:5, y:4x:4, y:4x:5, y:5None of the above
Introduction to c sharp 4.0 and dynamic

Introduction to c sharp 4.0 and dynamic

  • 1.
    Required SlideIntroduction toC# 4.0 and DynamicBy: Gieno Miaogieno.miao@live.com
  • 2.
    The Evolution ofC#C# 4.0Dynamic ProgrammingC# 3.0Language Integrated QueryRuby On Rails 2.0C# 2.0GenericsJava EE 5, Ruby On Rails 1.0C# 1.0Managed CodeMono announced, J2SE 1.4
  • 3.
    C# 4.0 LanguageInnovationsDynamically Typed ObjectsOptional and Named ParametersImproved COM InteroperabilityCo- and Contra-variance
  • 4.
    Why Dynamic?There isa lot of interest in accessing the highly dynamic object model of HTML DOMCOM is heavily used and inter op code could be easier to read and writeDynamic languages are becoming increasingly popular We need unified way to work with all of the above
  • 5.
    .NET Dynamic ProgrammingArchitectureIronPythonIronRubyC#VB.NETOthers…Dynamic Language RuntimeExpression TreesDynamic DispatchCall Site CachingPythonBinderRubyBinderCOMBinderJavaScriptBinderObjectBinder
  • 6.
    Dynamically Typed ObjectsCalculatorcalc = GetCalculator();int sum = calc.Add(10, 20);.NET objectobject calc = GetCalculator();TypecalcType = calc.GetType();object res = calcType.InvokeMember("Add",BindingFlags.InvokeMethod, null,newobject[] { 10, 20 });int sum = Convert.ToInt32(res);Dynamic Language objectScriptObject calc = GetCalculator();object res = calc.Invoke("Add", 10, 20);int sum = Convert.ToInt32(res);Statically typed to be dynamicdynamic calc = GetCalculator();int sum = calc.Add(10, 20);Dynamic method invocationDynamic conversion
  • 7.
    dynamic calc =GetCalculator();int sum = calc.Add(10, 20);Under the coverdynamic is a new type only in the compilerEncoded in IL as object + dynamic attributeOperations on a dynamic variable become CallSites, objects “interpreted” by the DLRmember selection deferred to run-timecache the result of the bindingsthe return type of a dynamic operation is dynamicSupport all types of operations on dynamicmethod call, property access, indexer access, operators, conversions
  • 8.
    dynamici = 3;Math.Abs(i);Underthe coverFor binding calls to .NET types there is a runtime C# binderDoes overload resolution using runtime types for dynamic argumentsOverload resolution changed to accommodate dynamic method callsDynamic arguments are treated as wildcards for overload resolution
  • 9.
    Under the coverWhendose the compiler dispatch dynamically?if the receiver of the call is dynamic ORif any of the arguments to the call are typed dynamicWe can dynamically dispatch to static methods 
  • 10.
    Under the coverdynamicd = newDynamicObject();d.Foo();You can now write your own object that does dynamic dispatchjust implement IDynamicObjectThe C# runtime binder can function as a fallback for calls to dynamic objectsif your object is “hybrid” and some of the methods are dynamically dispatched and some are regular methodsthe C# semantics will be applied if the Object cannot itself resolve a call
  • 11.
    IDynamicObjectpublicabstractclassDynamicObject : IDynamicObject{publicvirtualobjectGetMember(GetMemberBinderinfo);publicvirtualobjectSetMember(SetMemberBinder info, object value);publicvirtualobjectDeleteMember(DeleteMemberBinder info); publicvirtualobjectUnaryOperation(UnaryOperationBinder info);publicvirtualobjectBinaryOperation(BinaryOperationBinder info, objectarg);publicvirtualobject Convert(ConvertBinder info); publicvirtualobject Invoke(InvokeBinder info, object[] args);publicvirtualobjectInvokeMember(InvokeMemberBinder info, object[] args);publicvirtualobjectCreateInstance(CreateInstanceBinder info, object[] args); publicvirtualobjectGetIndex(GetIndexBinder info, object[] indices);publicvirtualobjectSetIndex(SetIndexBinder info, object[] indices, object value);publicvirtualobjectDeleteIndex(DeleteIndexBinder info, object[] indices); publicMetaObjectIDynamicObject.GetMetaObject();}
  • 12.
    Improved COM interoperabilityAutomaticobject -> dynamic mappingOptional and named parametersOptional “ref” modifierInterop type embedding (“No PIA”)Indexed properties
  • 13.
    object -> dynamicmappingWe need to cast((Excel.Range)xl.Cells[1,1]).Value2 = “ID”;xl.Cells[1,1].Value2 = “ID”;When the return type of a COM call is object you are forced to cast to a known typeMaking the code harder to understandIf the return type is dynamic, you can continue to “dot” on the return typeIf you typed something wrong the compiler won’t tell you
  • 14.
    Optional and namedparametersxlChart.ChartWizard(cellRange.CurrentRegion,    Constants.xl3DBar, Type.Missing, Excel.XlRowCol.xlColumns, 1, 2, false, xlSheet.Name, Type.Missing, Type.Missing, Type.Missing);Non-optional must be specifiedxlChart.ChartWizard(cellRange.CurrentRegion, Constants.xl3DBar, PlotBy: Excel.XlRowCol.xlColumns,SeriesLabels: 2, CategoryLabels: 1, HasLegend: false, Title: xlSheet.Name);Arguments evaluated in order writtenNamed arguments can appear in any order
  • 15.
    Optional and namedparametersOptional parameterspublicStreamReaderOpenTextFile( string path, Encodingencoding,booldetectEncoding,intbufferSize);publicStreamReaderOpenTextFile( string path, Encodingencoding = null,booldetectEncoding = true,intbufferSize = 1024);Named argumentOpenTextFile("foo.txt”);OpenTextFile("foo.txt", Encoding.UTF8, bufferSize: 4096);
  • 16.
    Optional “ref” modifierobjectfileName= "Test.docx";object missing = System.Reflection.Missing.Value;doc.SaveAs(reffileName,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing);doc.SaveAs("Test.docx");
  • 17.
    Under the coverThedefault value for a parameter is encoded with DefaultParameterValue attributeThe compiler inserts that value if a value is not specified for that parameterIf a default value is not specified we will use default (type)For COM the compiler will pass in Type.MissingThe compiler will rearrange the specified named parameters and then apply overload resolution
  • 18.
    Under the coverYoucan override methods that declare optional parametersThe value of the parameter comes from the static type you used to call the methodYou can rename a parameter in an overrideThe compiler will use the name found in the static type you used to call the method“Omit ref” only works for COM objectsThe compiler creates a variable to store the value you specified and passes the created variable “by ref” to COM
  • 19.
    Co- and Contra-variance.NETarrays are co-variantstring[] strings = GetStringArray();Process(strings);…but not safelyco-variantvoid Process(object[] objects) { … }void Process(object[] objects) { objects[0] = "Hello"; // Ok objects[1] = newButton(); // Exception!}Until now, C# generics have been invariantList<string> strings = GetStringList();Process(strings);C# 4.0 supports safe co- and contra-variancevoid Process(IEnumerable<object> objects) { … }void Process(IEnumerable<object> objects) {// IEnumerable<T> is read-only and// therefore safely co-variant}
  • 20.
    Safe Co- andContra-variancepublicinterfaceIEnumerable<T>{IEnumerator<T> GetEnumerator();}publicinterfaceIEnumerable<out T>{IEnumerator<T> GetEnumerator();}out= Co-variantOutput positions onlyCan be treated asless derivedpublicinterfaceIEnumerator<T>{ T Current { get; }boolMoveNext();}publicinterfaceIEnumerator<out T>{ T Current { get; }boolMoveNext();}IEnumerable<string> strings = GetStrings();IEnumerable<object> objects = strings;in= Contra-variantInput positions onlypublicinterfaceIComparer<T>{int Compare(T x, T y);}publicinterfaceIComparer<in T>{int Compare(T x, T y);}Can be treated asmore derivedIComparer<object> objComp = GetComparer();IComparer<string> strComp = objComp;
  • 21.
    Variance in C#4.0supported for interface and delegate typesstatically checked definition site variancevalue types are always invariantIEnumerable<int> is not IEnumerable<object>similar to existing rules for arraysref and out parameters need invariant type
  • 22.
    SummaryWe have anew type called dynamicCalls that involve variables of type dynamic are treated differently by compilerWe package extra information about the callCalls can be: method calls, property access, indexer call, operator callThere is a C# runtime binder to interpret the information (at runtime)It uses the runtime type for all dynamic argumentsIt uses the compile time type for all other arguments
  • 23.
    How dynamic worksCLRExpressionTreeCOM BinderExeIronPython BinderCompileRunBind callDynamic CallDelegateDLRC# Runtime BinderCache…
  • 24.
    ReviewWhat is thedynamic type?There is no dynamic type . There is only object.What operations are supported?A variable of type dynamic is assumed to support any kind of operation (method call, property access, indexer call and operator call)How is the information about the call stored?Using CallSites objects the compiler packages data about the call
  • 25.
    What does aCallSite contain?Information about the call being madeWhat type of call (method call, property access, etc)The name of the memberThe context of the callThe type arguments for the callInformation about the parameter and return typesIs it a constant? Is it passed by-ref, etc.
  • 26.
    Dynamic FAQWhen doyou go dynamic?When the target of the call OR any of the call arguments are dynamicWhat is the return type of a dynamic call?It is dynamic in most caseWhat about conversions and constructors?They are dispatched at runtime, but their return type is known at compile time
  • 27.
    Dynamic FAQWhat aboutprivate methods?Information about the context of call is embedded in the CallSite allowing the Binder to “do the right thing”Calling a method off a non-dynamic target with dynamic argumentsIt works as expected We embed the type of all the receiver in the CallSiteCan dynamic “cross” assembly boundaries?Yes, we decorate any dynamic parameter or return type with a DynamicAttributeIt works for generic types constructed with dynamic as well 
  • 28.
    Dynamic FAQCan Iuse named and optional with dynamic?Yes And also Co & Contra varianceWhere can’t I use dynamic?Lambda expressionsLINQCan’t use dynamic with method groupsThrow or catch statements
  • 29.
     Quiz!classBase {   publicvirtualvoid Foo(int x = 4, int y = 5) {        Console.WriteLine("x:{0}, y:{1}", x, y);    }}classDerived : Base {    publicoverridevoid Foo(int y = 4, int x = 5) {        Console.WriteLine("x:{0}, y:{1}", x, y);    }}classProgram {    staticvoid Main(string[] args) {        Base b = newDerived();        b.Foo(x: 4, y: 5);    }}Output:x:4, y:5x:5, y:4x:4, y:4x:5, y:5None of the aboveOutput:x:4, y:5x:5, y:4x:4, y:4x:5, y:5None of the above