1

I have a lot of functions that look like this. Each has N arguments and each creates an SQLparamater array with each paramater being of this very similar form.

[WebMethod]
public static string accessServer(string dataField1, string dataField2, string dataField3) {
    string value;
    SQLParamater[] param = new SQLParameter[len] // len is the amount of arguments
    param[0] = new SQLParameter("@dataField1", dataField1);
    param[1] = new SQLParameter("@dataField2", dataField2);
    param[2] = new SQLParameter("@dataField3", dataField3);
    ...

    // do something with param

    return value;
}

This looks like it can be done generically using a combination of Reflection and accessing the paramaters in a generic way.

Ideally a method of the form

public static SQLParamater[] getParams(someType paramaters)

and SQLParamater[] param = getParams(...)

I'm not sure how to pass on all the paramaters generically.

[Edit]

Note that the names of these datafields are important. It's not just an array of strings but rather a set of key/value pairs.

[/Edit]

Raynos
  • 166,823
  • 56
  • 351
  • 396

4 Answers4

3

You can use a function with variable arguments: name(params string[] arguments), so you can call, for example: name(arg1,arg2,arg3,arg4);

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
1

This has been asked about before (can't find that question though), the problem however is that while you can figure out the parameter names by using reflection MethodBase.GetCurrentMethod() you can't zip those names together with the parameter values because there's no way for you to access a parameter list of values.

There are other ways of trying to work around this very specific tiresome problem but I don't recommend doing it this way, it just doesn't make a lot of sense.

Now, given a method like this:

static void SomeMethod(string arg1, int arg2, object arg3)
{
}

You could do this:

static void Main()
{
    var b = 123;
    // this now becomes necessary as it's the only way of getting at the metadata 
    // in a presumable safe manner
    Expression<Action> x = () => SomeMethod("a", b, "a" + b); 
    var args = GetArgs(x);
    foreach (var item in args)
    {
        Console.WriteLine("{0}: {1}", item.Key, item.Value);
    }
}

And implement the GetArgs method like so (you still need a way of putting those values somewhere becuase the invocation never occurs):

static IDictionary<string, object> GetArgs(Expression<Action> x)
{
    var args = new Dictionary<string, object>();
    var m = (MethodCallExpression)x.Body;
    var parameters = m.Method.GetParameters();
    for (int i = 0; i < m.Arguments.Count; i++)
    {
        // an easy way of getting at the value, 
        // no matter the complexity of the expression
        args[parameters[i].Name] = Expression
            .Lambda(m.Arguments[i])
            .Compile()
            .DynamicInvoke();
    }
    return args;
}

You infer the collection of name/value pairs from the expression tree created by the compiler, it's doable but kind of odd.

John Leidegren
  • 59,920
  • 20
  • 131
  • 152
  • I think you meant [this question](http://stackoverflow.com/questions/4502821/how-do-i-translate-a-liststring-into-a-sqlparameter-for-a-sql-in-statement/4502866#4502866). – Oliver Jan 25 '11 at 10:51
  • @Oliver - No, that's definitely something else entirely. – John Leidegren Jan 25 '11 at 10:53
0

I think your API design is flawed if you need this, you would better have one method, which accepts a collection of some sort.

Code duplication like this is almost never the correct way to get things done.

EDIT

On topic:

I guess you can get the values from the stack: http://www.thescarms.com/dotnet/StackFrame.aspx

Matěj Zábský
  • 16,909
  • 15
  • 69
  • 114
  • I would do that if I wasn't limited by the way WebMethods work – Raynos Jan 25 '11 at 10:41
  • Did you try to extract the values from the stack? – Matěj Zábský Jan 25 '11 at 10:48
  • Turns out I can actaully pass non native types from the client over Ajax like `Dictionary`. Your correct the issue here is passing the paramaters one by one. – Raynos Jan 25 '11 at 11:11
  • `I guess you can get the values from the stack` that is not getting the values of the stack, that's just getting at the method currently executing. Which is generally achieved by calling `MethodBase.GetCurrentMethod`. That link is also wrong regarding what information is available when. A PDB file containing symbols can be loaded in release builds as well. – John Leidegren Jan 27 '11 at 07:01
0

we do it like this:

var dict=new Dictionary
            { 
               {"@param1",value1},
               {"@param2",value2},
               {"@param3",value3},
               {"@param4",value4},
               ....
            };

 DALayer.ExecuteProc("procName",dict);

In the ExecuteProc function you can iterate over Dictionary object and set params using KeyValuePair object. But if you have to setup the datatype, lengths etc for the parameters then you have to do more work like preparing the sql command to query about parameters or passing more complicated object as parameter that contains information about datatype, length and direction etc.

TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188