As of version v2.4, ROOT.NET included a new method of accessing ROOT objects using C#’s dynamic keyword. For example to create TObjString even if you don't have all the ROOT.NET libraries loaded:

            dynamic c = ((dynamic)ROOTNET.Utility.ROOTCreator.ROOT).TObjString("dude");
            Console.WriteLine("Name is {0}", c.Name);

This allows easy access to custom ROOT objects. The only requirement is that the ROOT object has a CINT dictionary. The interface is not fast (method calls have to go through the .NET dynamic run-time and then through CINT; and no effort has yet been made to optimize the .NET half of the code path).

This feature is experimental and the documentation here is not complete (obviously). Explicitly missing is the performance. For example, python performance is better than dynamic ROOT.NET right now because the code does not use any of the callsite optimizations that .NET makes available to it! Also, complete implementation of IEnumerable and other features does not yet exist.

Here is a short listing of pros and cons of using dynamic objects vs the full blown wrappers:

  • Pros
    • You need only download the Dynamic library. This is approximately 1 MB in size.
    • Any custom object for which there is no wrapper can be used, as long as CINT knows about it (i.e. there is a valid TClass for it).
    • Properties are more universal than in the wrappers.
  • Cons:
    • Access to dynamic methods can be very slow. x1000 slower than using the wrapper. If you have something inside a tight loop it is best to use the wrappers if possible.
    • There is no intellisense in the Visual Studio IDE.  I personally find intellisense amazingly useful.
    • Implementation is incomplete (but failures should be handled gracefully).

All Objects Are Dynamic

All ROOT.NET objects are dynamic. This means you can apply the dynamic keyword to any object that you have in your code and start using it as you wish.

All objects have some sort of ROOT.NET wrapper. In general, ROOT.NET will find the best wrapper it can for a particular object. For example, if you’ve implemented a TCustom object that is a subclass of TObject, in the following code:

            dynamic c = ((dynamic)ROOTNET.Utility.ROOTCreator.ROOT).TCustom();

Then the object c will contain a TObject wrapper. However, everything is called dynamically. There is a large advantage here: if you make a call to a TObject known method (even if it is overridden by your custom object), ROOT.NET will automatically used the high performance code path after the first call. Only if you call a method that is not known to TObject, but is known to TCustom will ROOT.NET use the slow dynamic .NET and CINT code paths.

All of this holds true also for non-TObject derived objects and namespace nested objects. In general, you can create any object dynamically that returns a valid TClass pointer in a call to TClass::GetClass(“object-name”).

Special Features

Because ROOT.NET code gets involved with any code requests on a dynamic objects an amazing amount of flexibility is available. Most features discussed here are meant to make ROOT.NET more useful in the .NET world.

Properties

If you reference a ROOT.NET wrapper as a property this will be converted into a method call in C++. For example, the following code:

actually calls GetXXX under the hood.

Resolution happens as follows if you try to access a property called XXX:

  1. If there is a method called XXX and it has no parameters, it will be called.
  2. If there is a method named GetXXX and it has no parameters, it will be called.
  3. An exception is thrown.

Trees

A ROOT.NET object of type NTree has special properties that allow one to easily iterate through its contents. There is a separate documentation page as Tree’s are, in general, a very complex topic.

Things To Note

For this feature to work a TApplication object must be created. If you don’t want the default one created, make sure you create one before you make your first dynamic access to ROOT – ROOT.NET will create the default one if it can’t find one already created!

If you end up with a dynamic object back that is a null, the system will have some difficulty with it as it won’t have a type. This isn’t true in the strongly typed world of C# – but in the dynamic world if the underlying system can’t guess what the type is, it can’t pass that information up to the CLR and .NET world.

There are lots of limitations. For example, the iterator interface isn’t implemented. Properties aren’t coded yet. Many types of arguments don’t work – for example, if you try to call a method with a reference argument it will call properly, but any changes that ROOT makes to the argument will probably not be reflected back into the .NET world.

Last edited Sep 8, 2014 at 9:27 PM by gwatts, version 8

Comments

krishnateja Apr 27, 2013 at 6:10 AM 
How to save a h.ShowBackground(80, "") into another histo ?