user559142
user559142

Reputation: 12517

.NET 4.0 / C# - Creating objects on the fly

I have 6 XDocuments:

XDocument parametersXDoc = new XDocument(new XElement(file.Root.Element("ArrayOfParameter")));
XDocument criteriaXDoc = new XDocument(new XElement(file.Root.Element("ArrayOfCriteria")));
XDocument sortfieldsXDoc = new XDocument(new XElement(file.Root.Element("ArrayOfSortField")));
XDocument selectedfieldsXDoc = new XDocument(new XElement(file.Root.Element("ArrayOfSelectedField")));
XDocument reportlayoutXDoc = new XDocument(new XElement(file.Root.Element("ReportLayout")));
XDocument dictionaryXDoc = new XDocument(new XElement(file.Root.Element("Dictionary")));

I want to pass them all to a method as an argument. I could pass them as an array, but then I would need to know the position/index of the XDocument I require - this seems messy.

Is it possible to create a temporary wrapper object on the fly (with properties) that point to each of the XDocument variables and pass this instead?

Upvotes: 5

Views: 12187

Answers (6)

You can create and manipulate dynamic objects on the fly, using the dynamic keyword or ExpandoObject in .NET4.0. The dynamic keyword is extremely powerful.

An OpenSource example of how it can be used successfully in a data-access layer can be found in the PetaPoco micro-ORM.

From MSDN:

Visual C# 2010 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation

ExpandoObject Code example

using System;
using System.Dynamic;
using System.Xml.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            // Creation and population of the ExpandoObject    
            // Add as many or few properties as you like. 
            // Property Types are set at runtime and for the lifetime of the
            // property 
            // Expando objects also support dynamic methods. 
            dynamic wrapper = new ExpandoObject(); 
            wrapper.FirstProperty = "Hello";
            wrapper.SecondProperty = "Dynamic";
            wrapper.AnotherProperty = "World!";
            wrapper.AnyTypeProperty = 1234;
            wrapper.XDocumentProperty = new XDocument();
            // etc 

            // Passing of ExpandoObject
            PassWrapperToFunction(wrapper);
            Console.ReadLine();
        }

        // .. 
        // Function signature of recipient
        private static void PassWrapperToFunction(dynamic wrapper)
        {
            Console.WriteLine("{0} {1} {2} {3}\n", 
                wrapper.FirstProperty, 
                wrapper.SecondProperty,
                wrapper.AnotherProperty, 
                wrapper.AnyTypeProperty);

            Console.WriteLine("Parameter types:\n{0}\n{1}\n{2}\n{3}\n{4}",
                wrapper.FirstProperty.GetType(), 
                wrapper.SecondProperty.GetType(),
                wrapper.AnotherProperty.GetType(), 
                wrapper.AnyTypeProperty.GetType(), 
                wrapper.XDocumentProperty.GetType());
        } 
    }
}

Output

enter image description here

Upvotes: 5

Bertie
Bertie

Reputation: 733

Why not use a dictionary - then you could either use a simple string key or perhaps use a unique property from the documents as the key. So for example :

public void FooMethod(Dictionary<String, XDocument> docDictionary)
{
    var doc1 = docDictionary["parametersXDoc"];
    var doc2 = docDictionary["criteriaXDoc"];
    blah blah blah
}

Cheers, Chris.

Upvotes: 0

Igarioshka
Igarioshka

Reputation: 677

you might consider creating a simple type with properties. passing anonymous type to a method looks kinda bad practice. if you still want to look at it, you might try this:

http://msdn.microsoft.com/en-us/library/bb397696.aspx

although, as I said:

To pass an anonymous type, or a collection that contains anonymous types, as an argument to a method, you can declare the parameter as type object. However, doing this defeats the purpose of strong typing. If you must store query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.

Upvotes: 0

Nitin Kumar
Nitin Kumar

Reputation: 109

If you dont want to pass a strongly typed object, then your quick and dirty options are :

  1. Pass an anonymous object :

new { Doc1=parametersXDoc , Doc2=criteriaXDoc , ... .... ..}

  1. Pass a Tuple :

new Tuple<XDocument,XDocument,XDocument,XDocument,XDocument,XDocument>

  1. Pass a Dictionary<String,XDocument>

Upvotes: 0

MattDavey
MattDavey

Reputation: 9017

It is possible to create a so called 'anonymous type', but that wouldn't allow you to access the properties in the other method without using dynamics.

What's so bad about just wrapping the whole lot in a class?

public class Documents
{
    public XDocument ParametersXDoc { get; set; }
    public XDocument CriteriaXDoc { get; set; }
    public XDocument SortfieldsXDoc { get; set; }
    public XDocument SelectedfieldsXDoc { get; set; }
    public XDocument ReportlayoutXDoc { get; set; }
    public XDocument DictionaryXDoc { get; set; }
}

That class probably took less time to write than your stackoverflow question ;)

Upvotes: 4

jerjer
jerjer

Reputation: 8760

I should use dictionary instead of an Array in this case will use the keys to identify each of them.

var parameters = new Dictionary<String, XDocument>();
parameters["parametersXDoc"] = new XDocument(new XElement(file.Root.Element("ArrayOfParameter")));
parameters["criteriaXDoc"] = new XDocument(new XElement(file.Root.Element("ArrayOfCriteria")));
parameters["sortfieldsXDoc"] = new XDocument(new XElement(file.Root.Element("ArrayOfSortField")));
parameters["selectedfieldsXDoc"] = new XDocument(new XElement(file.Root.Element("ArrayOfSelectedField")));
parameters["reportlayoutXDoc"] = new XDocument(new XElement(file.Root.Element("ReportLayout")));
parameters["dictionaryXDoc"] = new XDocument(new XElement(file.Root.Element("Dictionary")));

Upvotes: 1

Related Questions