tags:

views:

85

answers:

3

I understand how to get the names of parameters passed to a method, but let's say I have a method declaration as follows:

static void ParamsTest(string template, params object[] objects)

and I want to use object/property names in my template for substitution with real property values in any of the objects in my `objects' parameter. Let's then say I call this method with:

ParamsTest("Congrats", customer, purchase);

I will only be able to retrieve two parameter names trying to fill out the template, viz, template, and objects, and the names of the objects in the objects collection are forever lost, or not?

I could require a List<object> as my second parameter, but I feel there is somehow a more elegant solution, maybe with a lambda or something. I don't know, I'm not used to using lambdas outside of LINQ.

A: 

You could define a parameters object :

public class ParamsTestParams {
    public string A { get; set; }
    public string B { get; set; }

    public static readonly ParamsTestParams Empty = new ParamsTestParams();
}

Change the methods signature to :

ParamsTest(ParamsTestParams parameters)

And call your method like so :

ParamsTest(new ParamsTestParams { A = "abc" });

or :

ParamsTest(new ParamsTestParams { B = "abc" });

or :

ParamsTest(new ParamsTestParams { A = "abc", B = "xyz" });

or :

ParamsTest(ParamsTestParams.Empty); // instead of null so you don't have to do null checks in the method's body

and so on.

Andrei Rinea
could use an anonymous object instead in c#4
Mark
yes, but obtaining its members and their names inside ParamsTest is not a simple task - it involves reflection
Andrei Rinea
Added anonymous type example
Andrei Rinea
Or I could just use a Dictionary<string, object> :-)
ProfK
You can also reorder parameters in the call :)
Andrei Rinea
@Mark, I can do anonymous types in C# 3 already.
ProfK
my bad.. thought it was 4.0
Mark
A: 

I would probably just do it like this:

static void ParamsTest(string template, object[] objects)

and call it like this:

ParamsTest("Congrats", new object[] { customer, purchase });
snurre
Just as in my anonymous type sample, you don't really have type safety, also you don't have parameter naming.Also, you can be shorter in syntax from "new object[] { ... }" to "new [] { ... }"
Andrei Rinea
I really, really need parameter naming.
ProfK
Then I think Oded's suggestion of Dictionary<string,object> is your easiest option
snurre
+3  A: 

Inpsired by Mark I can offer an anonymous type answer :

using System;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            ParamsTest(new { A = "a", B = "b"});
        }

        public static void ParamsTest(object o)
        {
            if (o == null)
            {
                throw new ArgumentNullException();
            }
            var t = o.GetType();
            var aValue = t.GetProperty("A").GetValue(o, null);
            var bValue = t.GetProperty("B").GetValue(o, null);
        }
    }
}

However this DOES have drawbacks :

  • No type safety. I can pass in any object
  • I can pass in an anonymous type with different members and/or types than those expected
  • You should also do more checking than in this short sample
Andrei Rinea
You can also reorder parameters in the call :)
Andrei Rinea
+1 for me, lol.
Mark
I wish I could vote Mark up as well, but his is not an answer. Thanks, this is my chosen route.
ProfK
Let's upvote a random question/answer of Mark's! [I will]
Andrei Rinea