开发者

Can parameters be generically accessed?

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 SQL开发者_StackOverflow社区Parameter("@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]


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


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.


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜