Linq To XML: Generate Types with Nested Types using C#

In this article, we will have look at how can we generate Types with subtypes using Linq To XML

Suppose we have an XML file which holds information about Cars as their Model Name, Transmission details, Engine Details and some other information, like follows

<?xml version="1.0" encoding="utf-8" ?> 
<Cars>
 <Car Name = "Golf">
    <Transmission Type="Manual" Gears="5" />
    <Engine Type="diesel" Power="2000" />
 </Car>
 <Car Name = "Mazda">
    <Transmission Type="Automatic" Gears="4" />
    <Engine Type="Patrol" Power="2000" />
 </Car>
</Cars>

Now we have class named Car as Follows

    class Car
    {
        // struct Transmission
        public Transmission Transmission { get; set; }
        // struct Engine
        public Engine Engine { get; set; }
    }

Class car has two properties which are structs, Transmission and Engine

    struct Engine
    {
        // Type of Engine
        public string Type
        { get; set; }

        // Power of Engine
        public int Power
        { get; set; }
    }
    struct Transmission
    {
        // Type of Transmission
        public string Type
        { get; set; }

        // Type of Transmission
        public int Gears
        { get; set; }

        public override string ToString()
        { return Type + " " + Gears; }
    }

This is how we can parse the above XML document using XElement and Linq To XML and generate the required classes

                 // Load Document using XElement
                 XElement elements = XElement.Load("XMLFile.xml");

                 // using Linq To Xml parse and load Objects
                 List<Car> CarsList =
                 (from e in elements.Descendants("Car")
                 // get new Car object
                 select new Car
                 {
                     // get Name for the Car
                     Name = e.Attribute("Name").Value,

                     // get Transmission details for the Car
                     Transmission = new Transmission()
                     {
                         Type = e.Element("Transmission").Attribute("Type").Value,
                         Gears = Convert.ToInt32(e.Element("Transmission").Attribute("Gears").Value)
                     },
                     // get Engine details for the Car
                     Engine = new Engine()
                     {
                         Type = e.Element("Engine").Attribute("Type").Value,
                         Power = Convert.ToInt32(e.Element("Engine").Attribute("Power").Value)
                     }
                 }).ToList<Car>();

To work over the returned List of cars we can use many methods, one of which is foreach

            foreach (Car car in CarsList)
            {                
                Console.WriteLine(car.Name);                
                Console.WriteLine(car.Engine.Type);
                Console.WriteLine(car.Transmission.ToString());
                Console.WriteLine("--------------");  
            }

here is the output:

Advertisements

Check if class(T) inherits an interface(T)

The very first thing which comes to our mind is is operator like

bool IsDerived = a class is Interface

Well, that is not correct. why ? because

is operator is used to check whether the run-time type of an object
is compatible with a given type.

An expression where the use of is conforms to the syntax, evaluates to true, if both of the following conditions are met:

  • expression is not null.
  • expression can be cast to type. That is, a cast expression of the form
    (type)(expression) will complete without throwing an exception. For
    more information, see 7.6.6 Cast
    expressions.
  • Solution is to use:

    bool IsDerived = typeof(ISomeInterface).IsAssignableFrom(typeof(T));

    References

  • Does a Type Implement an Interface?
  • is operator
  • Linq-to-SQL, Linq-to-DataSet and Linq-to-Entities

    LINQ to SQL is an O/RM (object relational mapping) implementation that was provided in the .NET Framework “Orcas” (.NET Framework version 3.5) release.

    It allows us to model a relational database using .NET classes and query those models using LINQ notation / syntax. We can query the database and perform all operations like update, insert and delete etc.

    As per MSDN: ” It provides a run-time infrastructure for managing relational data as objects”

    Linq-to-DataSets is just LINQ, but it is used to query against the ADO.NET DataSets. As per MSDN : “LINQ to DataSet makes it easier and faster to query over data cached in a DataSet object”.

    Linq-to-Entities is better and provides more flexibility and is usable with many types of data sources and is not limited to SQL Server only, like Linq-to-SQL is. It uses Entity Framework in the background, as the ORM.

    Implicit versus Explicit implementation of Interfaces in C#

    What is the differences in implementing an interfaces implicitly or explicitly in C#?

    Suppose we have an interface IWriter as follows

        public interface IWriter
        {
            public void WrtiteTo()
            { }
        }
    

    Implicit: When we implement an interface implicitly, the implementing class exposes new behaviours. It is simply adding the methods, properties or other items required by the interface directly to the class and as public methods. So winding up, A member does this work for you in class which is implementing certain interface. Here is the sample which implements IWriter Interface implicitly:

        public class DocumentWriter : IWriter
        {
            #region IWriter Members
            public void WrtiteTo()
            {
                // Some Logic here
            }
            #endregion
        }
    

    Implicit: On the other hand Explicit implementation are exposed by the use of interface itself itself. Here is the sample which implements IWriter Interface Explicitly:

        public class DocumentWriter : IWriter
        {
            #region IWriter Members
            void IWriter.WrtiteTo()
            {
                 // Some Logic here
            }
            #endregion
        }