Click here to Skip to main content
Click here to Skip to main content

Tagged as

Dynamic Keyword In C# 4.0 - Part 2

, 19 Apr 2011
Rate this:
Please Sign up or sign in to vote.
Superb Example To Traverse an XML File. One should have an understanding of Dynamic Keyword before reading this article which I explained in Part 1

Introduction

Please refer to the below links before reading this article. It gives an idea of how to use TryGetMember method of DynamicObject class which is necessary to understand this article because we used it in our example for XmlNavigation.

Now, manipulating XElements can be done with methods of XElement objects and the syntax may be:

// Creates an XElement dynamically
XElement xmlNavigation = XElement.Parse(@"
                            <Emails>
                                <Email>
                                    <Id>1</Id>
                                    <Description>sanjay.patolia@gmail.com</Description>
                                </Email>
                                <Email>
                                    <Id>2</Id>
                                    <Description>sanjay.patolia@patni.com</Description>
                                </Email>
                            </Emails>
                            ");

var email = xmlNavigation.Elements("Email"); 

In the above example, to fetch all the "Email" elements, we used Elements("Emails") statement. In the same way, we use other methods too to manipulate other XML reading oprations. Here, though our work has been done for fetching elements, it does not come into easily readable format. We can achieve that kind of functionality using DynamicObject class and a dynamic keyword, which allows us to navigate through XML in easily readable format. We just need to keep track of XmlStructure.

Let's talk a bit about DynamicObject class.

DynamicObject class allows us to implement operations dynamically, when we try to get member values or set member values. Please refer to the above link for more information on DynamicObject.TryGetMember method. Here, we will look at TryGetMember method of DynamicObject class, which will be called when we will try to get values of properties which are not implemented in the class.

Let us see an example of XML Navigation using DynamincObject class and a dynamic keyword.

namespace XmlNavigationUsingDynamic
{
    class Program
    {
        static void Main(string[] args)
        {
            // Creates an XML file in memory
            dynamic xmlNavigation = new XmlNavigationUsingDynamic
                (XElement.Parse(@"
                            <Emails>
                                <Email>
                                    <Id>1</Id>
                                    <Description>sanjay.patolia@gmail.com</Description>
                                </Email>
                                <Email>
                                   <Id>2</Id>
                                   <Description>sanjay.patolia@patni.com</Description>
                                </Email>
                            </Emails>
                            "));
 
            // Taking collection of "Description" elements into IEnumerable<XElement>
            // Here, we can also take it into var type instead of IEnumerable<XElement>
            IEnumerable<XElement> descriptionNodes = xmlNavigation.Email.Description;
 
            // Printing an elements "Description"
            descriptionNodes.ToList().ForEach(emailDesc =>
            {
                Console.WriteLine(emailDesc);
            });
 
            Console.ReadKey(true);
        }
    }
 
    /// <span class="code-SummaryComment"><summary>
</span>    /// XmlNavigationUsingDynamic class
    /// This allows us to perform dynamic operations
    /// <span class="code-SummaryComment"></summary>
</span>    public class XmlNavigationUsingDynamic : DynamicObject, IEnumerable<XElement>
    { 
        /// <span class="code-SummaryComment"><summary>
</span>        /// Xml node to be crated
        /// <span class="code-SummaryComment"></summary>
</span>        IEnumerable<XElement> node = null;
 
        /// <span class="code-SummaryComment"><summary>
</span>        /// Initializes node member
        /// <span class="code-SummaryComment"></summary>
</span>        /// <span class="code-SummaryComment"><param name="nodes">XElements parameters</param>
</span>        public XmlNavigationUsingDynamic(params XElement[] nodes)
        {
            node = nodes;
        }
 
        /// <span class="code-SummaryComment"><summary>
</span>        /// Allows to implement code for dynamic operations
        /// will be called when we try to Get any member of this class
        /// <span class="code-SummaryComment"></summary>
</span>        /// <span class="code-SummaryComment"><param name="binder">Here we are using this to fetch 
</span>        /// name of the member which is being called<span class="code-SummaryComment"></param>
</span>        /// <span class="code-SummaryComment"><param name="result">Allows to assign a value to a property 
</span>        /// which is being called
        /// For example: 
        /// When we say, 
        ///         xmlNavigation.Email, it will call this method with 
        ///         name in binder object and 
        ///         when we set result object that will be returned to the caller
        /// <span class="code-SummaryComment"></param>
</span>        /// <span class="code-SummaryComment"><returns>true or false to say whether it was successful or not</returns>
</span>        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var genericNode = node.Elements(binder.Name).ToArray();
            result = new XmlNavigationUsingDynamic(genericNode);
            return true;
        }
 
        /// <span class="code-SummaryComment"><summary>
</span>        /// Gets enumerator
        /// <span class="code-SummaryComment"></summary>
</span>        /// <span class="code-SummaryComment"><returns></returns>
</span>        public IEnumerator<XElement> GetEnumerator()
        {
            return node.GetEnumerator();
        }
 
        /// <span class="code-SummaryComment"><summary>
</span>        /// Calls GetEnumerator method
        /// <span class="code-SummaryComment"></summary>
</span>        /// <span class="code-SummaryComment"><returns>IEnumerator</returns>
</span>        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

In the above example:

  1. // Creates an Xml file in memory
    dynamic xmlNavigation = new XmlNavigationUsingDynamic
    	(XElement.Parse(@"
                            <Emails>
                                <Email>
                                    <Id>1</Id>
                                    <Description>sanjay.patolia@gmail.com</Description>
                                </Email>
                                <Email>
                                    <Id>2</Id>
                                    <Description>sanjay.patolia@patni.com</Description>
                                </Email>
                            </Emails>
                            "));

    creates an XML file in memory.

  2. xmlNavigation.Email

    xmlNavigation is an object of XmlNavigationUsingDynamic class and .Email is a member (considering a member) of that class. So it is trying to access that member of that class. This statement will call the TryGetMember method, it performs an operation and sets result object which will be the base of "Description", because the result object is set to an object of XmlNavigationUsingDynamic class.

  3. xmlNavigation.Email.Description

    Description will be called from result (object set from TryGetMember method) and returns IEnumerable<XElement> because we have implemented IEnumerable<XElement> and node.GetEnumerator() method is called which is implemented from IEnumerable interface and returns IEnumerable<XElement> so at last we are iterating it to get element "Description".

So, look at the difference in traversing the XML file:

// Using typical XML traversing using XElements.
var email = xmlNavigation.Elements("Email");
 
// Using DynamicObject class XML traversing.
// We can use var here as required.
IEnumerable<XElement> descriptionNodes = xmlNavigation.Email.Description;

Thus, in this way we can perform other XML navigation operations too.

History

  • 19th April, 2011: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sanjay J Patolia
Software Developer Software Industry
India India
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pinmemberbartolo25-Apr-11 21:25 
GeneralRe: My vote of 5 PinmemberPatolia Sanjay25-Apr-11 21:31 
GeneralMy vote of 5 PinmemberGastonV25-Apr-11 19:38 
GeneralRe: My vote of 5 PinmemberPatolia Sanjay25-Apr-11 21:31 
Generalneed to explain in deep- vote of 4 PinmemberPranay Rana21-Apr-11 19:09 
GeneralRe: need to explain in deep- vote of 4 PinmemberPatolia Sanjay25-Apr-11 21:33 
Generalpretty neat, but not much different from standard XLINQ which does the same PinmvpSacha Barber21-Apr-11 2:34 
GeneralRe: pretty neat, but not much different from standard XLINQ which does the same Pinmemberbartolo25-Apr-11 21:27 
GeneralRe: pretty neat, but not much different from standard XLINQ which does the same PinmvpSacha Barber25-Apr-11 21:32 
GeneralRe: pretty neat, but not much different from standard XLINQ which does the same Pinmemberbartolo25-Apr-11 21:41 
GeneralRe: pretty neat, but not much different from standard XLINQ which does the same PinmvpSacha Barber25-Apr-11 21:42 
GeneralRe: pretty neat, but not much different from standard XLINQ which does the same PinmemberPatolia Sanjay25-Apr-11 21:35 
GeneralRe: pretty neat, but not much different from standard XLINQ which does the same PinmvpSacha Barber25-Apr-11 21:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 19 Apr 2011
Article Copyright 2011 by Sanjay J Patolia
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid