Labels

Wednesday, October 13, 2010

Silverlight Threading

Threading in Silverlight is no more new than the regular Threading works.
However there are two new things to know here.

·         DispatcherTimer
·         BackgroundWorker

DispatcherTimer

Let’s understand the quick need of Dispatcher by below example.

Much like .NET client applications (e.g. WPF & WinForms applications), Silverlight supports a Single-Threaded Apartment Model. In this model, a single thread runs your entire application and owns all the objects that represent user-interface elements. The thread that creates them  owns them, and other threads can’t interact with them directly.
If this rule is violated – as shown in below example, by trying to access a user-interface object from a background thread–you’re certain  to cause an immediate exception, a lock-up, or a subtler problem.


Problem

protected void Unnamed1_Click(object sender, RoutedEventArgs e)
{       
   ThreadStart thst = new ThreadStart(ThreadRole);
   Thread th = new Thread(thst);
   th.Start();      
}


private void ThreadRole()
{
  try
  {
    Thread.Sleep(2000);
    Label1.Text = "Done"; // Does Not Affects
  }
  catch (Exception ex)
  {
    Throw ex// Invalid cross-thread access Exception
  }
}



This is where Dispatcher comes in picture. The dispatcher owns the main application thread and thus able to perform the above violated work.


Solution using Dispatacher

private void ThreadRole()
{
  Thread.Sleep(2000);
  this.Dispatcher.BeginInvoke(delegate()
  {
    Label1.Text = "Done"// Makes Affect
  });
}


The DispatcherTimer doesn’t offer true multithreaded execution. Instead, it triggers a periodic Tick event on the main application thread.
This advantage of having the tick event always executing on the main application thread, side steps synchronization problems and the other headaches. Refer above example.

This event interrupts whatever else is taking place in your application, giving you a chance to perform some work. I.e It halts/locks the main application / user interface.
This behavior on one hand side steps synchronization problems, but on the other hand it also introduces a number of limitations. I.e. This is fine if you need to  frequently perform small amounts of work,  but if it is a time-consuming task, then the user interface locks up until it’s finished. Thus, the DispatcherTimer doesn’t help you make a user interface more responsive.

So the case where time-consuming task is required, you need the real multithreading.

Here are examples of some small amounts of work that can be handled thru DispatcherTimer.
·         For example, it’s a great way to periodically check a web service for new data.  As we know all web service calls are asynchronous and are carried out on a background thread. Thus, we can use the   DispatcherTimer to just launch the web service call asynchronously and come back. This will enable the time-consuming download to take place on a background thread.

The BackgroundWorker (System.ComponentModel.BackgroundWorker)

The BackgroundWorker component, which was first introduced with .NET 2.0 to simplify threading considerations in WinForms applications.
Fortunately, the  BackgroundWorker is equally at home in Silverlight.

The BackgroundWorker component is one of the simplest and safest approaches to multithreading.
This gives you a nearly foolproof way to run a time-consuming task on a separate thread.
Silverlight recommends whenever possible, it’s better to use the straightforward BackgroundWorker component than the lower-level Thread class.
Reason being –

·         It supports event-based model to notify client application about Progress/Cancellation.
·         Secondly, to achieve this event-based model, it uses the dispatcher behind the scenes. Thus abstracts away the marshalling issues with an event-based model. (As discussed above).

The BackgroundWorker’s core events are DoWork, ProgressChanged, and RunWorkerCompleted.


Solution using Dispatacher

private BackgroundWorker backgroundWorker = new BackgroundWorker();
public BackgroundWorkerTest()
{
 InitializeComponent();
 backgroundWorker.WorkerReportsProgress = true;
 backgroundWorker.WorkerSupportsCancellation = true;

 backgroundWorker.DoWork += backgroundWorker_DoWork;
 backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
 backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
}


Note
·         BackgroundWorker is perfect if you have a single asynchronous task that runs in the background from start to finish (with optional support for progress reporting and cancellation).
·         If you have something else in mind—for example, an asynchronous task that runs throughout the entire life of your application or an asynchronous task that communicates with your application while it does its work—you must design a customized solution that uses the threading features you’ve already seen.


Hope this helps.

Regards,
Arun Manglick

Thursday, October 7, 2010

Design pattern - IOC & DI

The Inversion of Control (IoC) pattern, is also known as Dependency Injection. Or In other words - IOC is implemented using DI. Or DI is the main method to implement IoC.
The target behind applying IOC and DI is to build Loosely Coupled Software Architecture.

IoC is not a new concept, however. It has been around for several years now. Using OO design principles and features such as Interface, Inheritance, and Polymorphism, the IoC pattern enables better software design that facilitates reuse, Loose Coupling, and easy testing of software components

The basic principle of IOC stands on the base of Bollywood principle – "Do not call us we will call you".
In other words it like aggregated class (here Address) saying to the container class (here Customer), do not create me I will create myself using some one else.

This article discusses IoC and demonstrates how to use this pattern in your software design with/without using any of the open source frameworks.

IoC Design Pattern

Lets understand this with an example.

Assume Class A has a relationship with Class B: it wants to use the services of Class B. The usual way to establish this relationship is to instantiate Class B inside Class A.




public class A
{
  private B b;

  public A()
  {
    b=new B();
  }
}

Listing 1 - Class A Directly Refers Class B 


public class A
{
  private B b;

  public A()
  {
    C c=new C();
    b=new B(c);
  }
}

Listing 2. Class A Directly Refers Class B and Class C

Though this approach works, it creates tight coupling between the classes. You can't easily change Class B without modifying Class A.
Here are the problems.

·         This design assumes that - Class B is a concrete class that has a default constructor. Now If Class B is changed to have a non-default constructor, then Class A would also require a change.
·         Also If Class B changed to have a non-default constructor, which takes Class C , then again the Class A would require a change.
·         Now If Object "a" owns both Object "b" and Object "c". If Class B or Class C changes at all, then Class A needs to change as well.

In essence, a simple design of a simple class with implicit design assumptions becomes a maintenance nightmare in the future. Consider how difficult making changes would be if you had this scenario in a typical application with several classes.

Here comes the usage of 'IoC pattern Framework'.

Let's re-understand the above problem with realistic objects.
In the above code, the biggest issue is the tight coupling between classes. The same is found here in real-time example also.

IOC - Problem



Here, the Customer class depends on the Address object. So for any reason Address class changes it will lead to change and compiling of 'ClsCustomer' class also. I.e. You can't easily change Address class without modifying 'ClsCustomer' Class. For e.g.

·         If Class Address is changed to have a non-default constructor, then Class Customer would also require a change.
·         Now If Object "Customer" owns two Objects "Address" and "SocietyDetail". If these two Class changes at all, then Class Customer needs to change as well.

So let's put down problems with this approach:

  • The biggest problem is that Customer class controls the creation of Address object.
  • Address class is directly referenced in the Customer class which leads to tight coupling between address and customer objects.
  • Customer class is aware of the Address class type. So if we add new Address types like home address, office address it will lead to changes in the customer class also as customer class is exposed to the actual address implementation.

In essence - If for any reason the Address object is not able to create,  the whole Customer class will fail in the constructor initialization itselfVery High/Tight Coupling.

Solution: IoC

The main problem roots from the customer class creating the address object. The solution is:

·         Shift the task/control of object creation from the customer class to some other entity – Problem Solved.
·         In other sentence if we are able to Invert this control to a third party we have found our solution. So the solution name is IOC (Inversion of control).

This is the opposite of using an API, where the developer's code makes the invocations to the API code. Hence, frameworks Invert the control: it is not the developer code that is in charge, instead the framework makes the calls based on some stimulus. I.e. Do not call us we will call you.

This solutiuon Achieves The Decoupling, and is refrerred to as - IOC (Inversion of control).

Here is the solution detail - Expose a method which allows us to set the address object. I.e. Let the address object creation be delegated to the IOC framework. IOC framework can be a class, client class or some kind of IOC container. So it will be two step procedure IOC framework creates the address object and passes this reference to the customer class.

Solution – Using DI

clsAddress objAddress = new clsAddress(..);

clsCustomer objCustomer = new clsCustomer;
objCustomr.setAddress(objAddress); // IOC Framework


The basic principle of IOC stands on the base of Hollywood principle - Do not call us we will call you (Translating for struggling actors)
In other words it like Address class saying to the Customer class, Do Not Create Me I Will Create Myself Using Some One Else.

There are two principles of IOC:

  • Main classes (Here like Customer) aggregating other classes (Here like Address) should not depend on the direct implementation of the aggregated classes (Here like Address). Both the classes should depend on abstraction. So the customer class should not depend directly on the address class. Both address and customer class should depend on an abstraction either using interface or abstract class.
  • Abstraction should not depend on details, details should depend on abstraction.


Ok, now we know the problem, let's try to understand the broader level solution. IOC is implemented using DI (Dependency injection).
We have discussed on a broader level about how to inject the dependency in the previous sections. In this section we will dive deeper in to other ways of implementing DI.

Several open source IoC frameworks like Windsor Container, Castle Windsor, Spring, PicoContainer, and HiveMind support the IoC pattern. While the general IoC principle is simple, each of these frameworks supports different implementations and offers different benefits. The IoC pattern can be implemented in four ways, as mentioned below.




The figure shows how IOC and DI are organized. So we can say IOC Is A Principle while DI Is A Way Of Implementing IOC. In DI we have four broader ways of implementing the same:

  • Constructor way
  • Exposing setter and getter (As in above examples)
  • Interface implementation
  • Service locator

Constructor Methodology

In this methodology we pass the object reference in the constructor itself. So when the client creates the object he passes the object in the constructor while the object is created.
Its main advantage is that only the creator knows about the referenced object.
This methodology is not suited for client who can only use default constructors. Then you need to go with a setter-based IoC.

IOC - Constructor Methodology

Figure: - Constructor based DI

Setter and Getter

This is the most commonly used DI methodology. The dependent objects are exposed through set/get methods of classes.
Setter-based IoC is good for objects that take optional parameters and objects that need to change their properties many times during their lifecycles.
The bad point is because the objects are publicly exposed it breaks the encapsulation rule of object oriented programming.

IOC – Setter & Getter

Figure: - Getter and Setter

 

In this type of IoC, objects implement a specific interface from the IoC framework, which the IoC framework will use to properly inject the objects.
One of the main advantages of this type is that it doesn't need an external configuration file to configure the object references. Since you need to use the IoC framework's marker interface, the IoC framework knows how to glue the objects together.
The main disadvantage of this approach is that the marker interface ties your application to a specific IoC framework. 

You can see in figure 'Interface based DI' we have implemented an interface 'IAddressDI' which has a 'setAddress' method which sets the address object.
This interface is then implemented in the customer class. External client / containers can then use the 'setAddress' method to inject the address object in the customer object.



Figure: - Interface based DI



The other way to inject dependency is by using service locator.
Your main class in need to aggregate the child object, will use the service locator to obtain instance of the address object.
The service locator class does not create instances of the address object, it provides a methodology to register and find the services which will help in creating objects.



Figure: - Service locator




Here we'll see how we can implement DI using 'Programatically' and 'Open Source IoC Framework - Windsor container'

If you are starting a new project, you can choose any of the open source IoC frameworks based on your needs.
If you want to use the IoC pattern in your existing project then you need to write your own classes that support IoC. Though the open source frameworks offer off-the-shelf components and may provide many more features than your own implementation, you can still develop a set of classes that support the IoC pattern using either of the above approach.

Here for example – Constructor Approach.

interface IAddress
{
   void AddAddress(string address);
}
public class Address : IAddress
{
   public string address;

   public void AddAddress(string address)
   {
      this.address = address;
   }
}

public class ClsCustomer
{
   IAddress address;

   public ClsCustomer(IAddress address)
   {
     this.address = address;
   }

   public string GetAddress()
   {
      Type c = Type.GetType("Address", true, true);
      if (typeof(IAddress).IsAssignableFrom(c))
      {
         return (objAddress as Address).MyAddress;
      }
      return string.Empty;
   }
}

class Client
{
   public void Run()
   {
      IAddress objAddress = new Address();
      objAddress.AddAddress("India");
           
      ClsCustomer customer = new ClsCustomer(objAddress);
      string address = customer.GetAddress();
   }       
}



Ok, now lets see how this will work if we use the Windsor container.

Figure 'Windsor container' shows how it looks like. So

·         Step 1 creates the Windsor container object.
·         Step 2 and 3 register the types (Iaddress) and concrete objects(clsAddress, clsCustomer) in the container.
·         Step 4 requests the container to create the customer object. In this step the container resolves and set the address object in the Constructor.
It's like - ClsCustomer customer = new ClsCustomer(objAddress);
·         Step 5 releases the customer object.
 
IOC – Interface Based


Figure: - Windsor container 

In actual implementation using the container we never use client code as above, rather we use config files.
You can see from figure 'Creating using config files' we have better flexibility to add more objects. In config file we need to define all the components in the components section.

The XmlInterpreter object helps to read the config file to register the objects in the container.
Using the Container.Resolve method we have finally created the customer object.
So the container plays the mediator role of understanding the Customer object and then injecting the Address object in the customer object through the constructor.

 



Figure: - Creating using config files


References: Link1, Link2

Hope this helps.

Thanks & Regards,
Arun Manglick

IsAssignableFrom

This is about checking the glue between Interface and Class Implementing the Interface.

 

 

public interface ISilverlightClientConfigProvider

{

    object GetClientConfigBlock(string moduleHint, string configBlockName);

}

 

 

public class UserProfileConfigProvider : ISilverlightClientConfigProvider

{

  // Code Here

}

 

public class EndPointConfigProvider : ISilverlightClientConfigProvider

{

  // Code Here

}

 

String str = "CTLS.ICLS.UX.ClientConfigProviders.UserProfileConfigProvider";

 

Type c = Type.GetType(str, true, true);

if (typeof(ISilverlightClientConfigProvider).IsAssignableFrom(c))

{

  ISilverlightClientConfigProvider provider = Activator.CreateInstance(c) as ISilverlightClientConfigProvider;

  if (null != provider)

  {}

}

 

 

Hope this helps.


Arun Manglick

Friday, October 1, 2010

C# 4.0 Features

C# 4.0 is the latest version of the C# programming language, which was released in April 11, 2010

·         Named and Optional Arguments
·         Dynamic Binding
·         CoVariance & ContraVariance
·         COM specific interop features
·         Indexed Properties


Named & Optional Arguments

This is similar to default values as seen in Visual Basic and C++. For example:




private void Increment(ref int x, int dx = 1)
{
  x += dx;
}

int x = 0;
Increment(ref x);    // dx takes the default value of 1
Increment(ref x, 2); // dx takes the value 2


public void M(int x, int y = 5, int z = 7);

M(1, 2, 3);
M(1, 2);   // Equivalent to M(1, 2, 7)
M(1);      // Equivalent to M(1, 5, 7)


It is also possible to explicitly specify Parameter Names In Method Calls.
The only restriction is that named parameters must be placed after the unnamed parameters.
Parameter names can be specified for both optional and required parameters, and can be used to improve readability or arbitrarily reorder arguments in a call.

For example:




Stream OpenFile(string name, FileMode mode = FileMode.Open, FileAccess access = FileAccess.Read)
 { ... }

OpenFile("file.txt"); // use default values for both "mode" and "access"
OpenFile("file.txt", mode: FileMode.Create); // use default value for "access"
OpenFile("file.txt", access: FileAccess.Read); // use default value for "mode"
OpenFile(name: "file.txt", access: FileAccess.Read, mode: FileMode.Create);


public void M(int x, int y = 5, int z = 7);

M(1, z: 3);
M(x: 1, z: 3);
M(z: 3, x: 1);  //Reversing the order of arguments

Optional parameters make interoperating with COM easier. Previously, C# had to pass in every parameter in the method of the COM component, even those that are optional. For example:




object fileName = "Test.docx";
object missing = System.Reflection.Missing.Value;

doc.SaveAs(ref fileName, 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);


With support for optional parameters, the code can be shortened as: doc.SaveAs(ref fileName);
Which, due to the now optional ref keyword when using COM, can further be shortened as: doc.SaveAs(fileName);

Overload resolution


Named and optional arguments affect overload resolution, but the changes are relatively simple:
A signature is applicable if all its parameters are either optional or have exactly one corresponding argument (by name or position) in the call which is convertible to the parameter type.
Betterness rules on conversions are only applied for arguments that are explicitly given – omitted optional arguments are ignored for betterness purposes.

Thumb Rule: If multiple signatures are equally good, one that does not omit optional parameters is preferred.




M(string s, int i = 1);
M(object o);
M(int i, string s = "Hello");
M(int i);


Call - M(5); // M(int)

Given these overloads, we can see the working of the rules above.

·         M(string,int) is not applicable because 5 doesn't convert to string.
·         M(int,string) is applicable because its second parameter is optional, and so, obviously are M(object) and M(int).

·         M(int,string) and M(int) are both better than M(object) because the conversion from 5 to int is better than the conversion from 5 to object.
·         Finally M(int) is better than M(int,string) because no optional arguments are omitted.
·         Thus the method that gets called is M(int).

Dynamic Binding

Dynamic binding allows you to write method, operator and indexer calls, property and field accesses, and even object invocations which bypass the C# static type checking and instead gets resolved at runtime.
Dynamic types, which means the types will be determined during the runtime and any error that is produced will not affect compilation of the project.

Dynamic binding offers a unified approach to invoking things dynamically. With dynamic binding, when you have an object in your hand, you do not need to worry about whether it comes from COM, IronPython, the HTML DOM, reflection or elsewhere; you just apply operations to it and leave it to the runtime to figure out what exactly those operations mean for that particular object.
This affords you enormous flexibility, and can greatly simplify your code, but it does come with a significant drawback: Static typing is not enforced for these operations.

See the code below :




public static void Main(string[] args)
{
   dynamic obj = GetObject(); // C# 4.0 introduces a new static type called 'dynamic'
   obj.CallMe(10);
}

public static dynamic GetObject()
{
 Dynamic obj = new NamedAndOption();
 Return obj;
}


int GetLength(dynamic obj)
{return obj.Length;}

GetLength("Hello, world");         // A string has a Length property,
GetLength(new int[] { 1, 2, 3 }); // and so does an array,
GetLength(42);                         // but not an integer - An exception will be thrown here at run-time


Here the dynamic object is created and a method is invoked. As this is truly dynamic, everything will be evaluated in runtime and hence you can call CallMe() or even CallMe2(which is not present) during compile time and this will evaluated during runtime and produce errors.

Dynamic lookup is performed using three distinct mechanisms:

·         COM IDispatch for COM objects,
·         IDynamicMetaObjectProvider DLR interface for objects implementing that interface. Thus any C# class can therefore intercept dynamic calls on its instances by implementing IDynamicMetaObjectProvider.
·         Relection for all other objects.

The dynamic type


C# 4.0 introduces a new static type called dynamic.
When you have an object of type dynamic you can "do things to it" that are resolved only at runtime:

dynamic d = GetDynamicObject(…);
d.M(7);

The C# compiler allows you to call a method with any name and any arguments on d because it is of type dynamic.
At runtime the actual object that d refers to will be examined to determine what it means to "call M with an int" on it.

dynamic d = 7; // compile-time implicit conversion
int i = d;     // runtime implicit conversion

Dynamic operations


Not only method calls, but also field and property accesses, indexer and operator calls and even delegate invocations and constructor calls can be dispatched dynamically:




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



How different with 'Var':

After the introduction of "var" in C# 3.5, the use of anonymous types increased rapidly. var is determined during compile time, and it is Implicitly Typed Variable so it can not be a return type of a method.
Dynamic on the other hand can be a part of return type or argument of a method and will act during runtime when actual object is set to it.


CoVariance & ContraVariance

Let's first understand these two concepts in easy words.

·         This is about using using two modifiers out and in  - As 'Type Parameters' on a generic type.
·         Variant type parameters can only be declared on interfaces and delegate types, due to a restriction in the CLR.
·         When applicable - Variance only applies when there is a Reference Conversion between the type arguments. For example, an IEnumerable<int> is not an IEnumerable<object> because the conversion from int to object is a boxing conversion, not a reference conversion.

Variance


The following generics aspect is not allowed – Surprising!!




IList<string> strings = new List<string>();
IList<object> objects = strings; // Not Allowed
IEnumerable <object> objects = strings; // Not Allowed

The second & third assignment – Ideally should be allowed- As you can assign Child to any Parent object as Parent is larger type and hold properties of Child.
However, surprisingly, this is disallowed – Reason being, Strings do not have the same element type as Objects. i.e. If it were allowed you could write:




objects[0] = 5;
string s = strings[0];

This is like, allowing an int to be inserted into a list of strings and subsequently extracted as a string. This would be a breach of type safety. Thus disallowed.
Here comes the usage of Covariance & Contravariance.

Variance is about allowing assignments such as this in cases where it is safe. The result is that a lot of situations that were previously surprising now just work.
See the below quick example.

In .NET 4.0 the IEnumerable<T> interface will be declared in the following way:



public interface IEnumerable<out T> : IEnumerable
{
  IEnumerator<T> GetEnumerator();
}

The "out" in these declarations is a new C# 4.0 modifier which signifies that the T can only occur in output position in the interface – the compiler will complain otherwise.
In return for this restriction, the interface becomes "covariant" in T, which means that an IEnumerable<A> is considered an IEnumerable<B> if A has a reference conversion to B.
As a result, any sequence of strings is also e.g. a sequence of objects. Thus the below becomes allowed.

IEnumerable <object> objects = strings; // Becomes Allowed Now (In C# 4.0)
Now let's understand this concept more.

Before that it's better to know - Generic Interfaces and Delegates only can have the Variance feature. i.e. Their type parameters can be marked as covariant or contravariant, using keywords out and in, respectively. These declarations are then respected for type conversions, both implicit and explicit, and both compile-time and run-time.

CoVariance

If you have a class hierarchy, Parent and Child (as name mentioned). Now ideally you can assign Child to any Parent object as Parent is larger type and hold properties of Child.
Now if you try to write come code as mentioned below.


CoVariance – Error Code

namespace CoVarinace
{
    class Vegetable { }
    class Potato : Vegetable { }

    class Program
    {
        delegate T MyFunc<T>();

         static void Main(string[] args)
         {
             MyFunc<Potato> potato1 = () => new Potato();  
             MyFunc<Vegetable> veg = potato1; // Fail
         }
    }
}


This code will fail with the below error message - "Cannot implicitly convert type ' CoVarinace.Program.MyFunc<CoVarinace.Potato>' to 'CoVarinace.Program.MyFunc<CoVarinace.Vegetable>' 
Here comes the usage of the new feature – 'CoVariance' -  delegate T MyFunc<out T>();

See the modified code.

CoVariance – No Errror

namespace CoVarinace
{
    class Vegetable { }
    class Potato : Vegetable { }

    class Program
    {
        delegate T MyFunc<out T>();

         static void Main(string[] args)
         {
             MyFunc<Potato> potato1 = () => new Potato();
             MyFunc<Vegetable> veg = potato1; //Covariance
         }
    }
}



ContraVariance

This works with generic delegate which returns nothing but takes a parameter.
See the code.


ContraVariance – Error Code

namespace ContraVarinace
{
    class Vegetable { }
    class Potato : Vegetable { }

    class Program
    {
        delegate void MyAction<T>(T a);

        static void Main(string[] args)
        {
            MyAction<Vegetable> action1 = (veg) => {Console.WriteLine(veg); };
            MyAction<Potato> potato1 = action1;
        }
    }
}


This will throw you an error - Cannot implicitly convert type 'ContraVarinace.Program.MyAction<ContraVarinace.Vegetable>' to ' ContraVarinace.Program.MyAction<ContraVarinace.Potato>'  
With a little modification the below code will work without any issue, you just need to put the keyword in.

delegate void MyAction<in T>(T a);


ContraVariance – No Error

namespace ContraVarinace
{
    class Vegetable { }
    class Potato : Vegetable { }

    class Program
    {       
        delegate void MyAction<in T>(T a);

        static void Main(string[] args)
        {
            MyAction<Vegetable> action1 = (veg) => { Console.WriteLine(veg); };
            MyAction<Potato> potato1 = action1;
        }
    }
}

Limitations


·         Variant type parameters can only be declared on interfaces and delegate types, due to a restriction in the CLR.
·         Variance only applies when there is a reference conversion between the type arguments. For instance, an IEnumerable<int> is not an IEnumerable<object> because the conversion from int to object is a boxing conversion, not a reference conversion.

Indexed properties

Many COM APIs expose "Indexed Properties" which are essentially properties with parameters. C# will not allow you to declare indexed properties, but to the extent that non-C# APIs expose them, will now allow you to access these using element access syntax. So instead of
o.set_P(i+1, o.get_P(i) * 2);
You can now write the more intuitive
o.P[i+1] = o.P[i] * 2;

Limitations

A few COM interface features still are not surfaced in C#, most notably default properties. As mentioned above these will be respected if you access COM dynamically, but statically typed C# code will still not recognize them.

Larger COM Example


Here is a larger Office automation example that shows many of the new C# features in action.




using System;
using System.Diagnostics;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
class Program
{
    static void Main(string[] args) {
        var excel = new Excel.Application();
        excel.Visible = true;
        excel.Workbooks.Add();                                    // optional arguments omitted
        excel.Cells[1, 1].Value = "Process Name";           // no casts; Value dynamically 
        excel.Cells[1, 2].Value = "Memory Usage";          // accessed
        var processes = Process.GetProcesses()
            .OrderByDescending(p =&gt; p.WorkingSet)
            .Take(10);
        int i = 2;
        foreach (var p in processes) {
            excel.Cells[i, 1].Value = p.ProcessName;        // no casts
            excel.Cells[i, 2].Value = p.WorkingSet;           // no casts
            i++;
        }
        Excel.Range range = excel.Cells[1, 1];               // no casts
        Excel.Chart chart = excel.ActiveWorkbook.Charts. Add(After: excel.ActiveSheet);  // named and optional arguments
        chart.ChartWizard(
            Source: range.CurrentRegion,
            Title: "Memory Usage in " + Environment.MachineName);   //named+optional
        chart.ChartStyle = 45;
        chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
            Excel.XlCopyPictureFormat.xlBitmap,
            Excel.XlPictureAppearance.xlScreen);
        var word = new Word.Application();
        word.Visible = true;
        word.Documents.Add();      // optional arguments
        word.Selection.Paste();
    }
}


The code is much more terse and readable than the C# 3.0 counterpart.

Hope this helps.

Regards,
Arun Manglick





DISCLAIMER:
This email (including any attachments) is intended for the sole use of the intended recipient/s and may contain material that is CONFIDENTIAL AND PRIVATE COMPANY INFORMATION. Any review or reliance by others or copying or distribution or forwarding of any or all of the contents in this message is STRICTLY PROHIBITED. If you are not the intended recipient, please contact the sender by email and delete all copies; your cooperation in this regard is appreciated.



--
Arun Manglick
(Software Engineer)