参数可以一般访问吗?

时间:2011-01-25 10:29:25

标签: c#

我有很多看起来像这样的功能。每个都有N个参数,每个参数都创建一个SQLparamater数组,每个参数都是这种非常相似的形式。

[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;
}

这似乎可以通过使用Reflection的组合以及以通用方式访问参数来一般地完成。

理想情况下是表格的方法

public static SQLParamater[] getParams(someType paramaters)

SQLParamater[] param = getParams(...)

我不确定如何一般地传递​​所有参数。

[编辑]

请注意,这些数据字段的名称重要。它不仅仅是一个字符串数组,而是一组键/值对。

[/编辑]

4 个答案:

答案 0 :(得分:3)

您可以使用具有可变参数的函数:name(params string[] arguments),以便您可以调用,例如:name(arg1,arg2,arg3,arg4);

答案 1 :(得分:1)

之前已经问过这个问题(虽然找不到问题)但问题是,虽然您可以通过使用反射MethodBase.GetCurrentMethod()找出参数名称,但您无法将这些名称与参数值,因为您无法访问参数值列表。

还有其他方法可以解决这个非常棘手的问题,但我不建议这样做,它只是没有多大意义。

现在,给出一个像这样的方法:

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

你可以这样做:

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);
    }
}

并像这样实现GetArgs方法(你仍然需要一种方法将这些值放在某处,因为调用永远不会发生):

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;
}

您可以从编译器创建的表达式树中推断出名称/值对的集合,它是可行的,但有点奇怪。

答案 2 :(得分:0)

我认为如果你需要这个API设计是有缺陷的,你最好有一个方法,它接受某种类型的集合。

像这样的代码重复几乎不是完成任务的正确方法。

修改

关于主题:

我猜你可以从堆栈中获取值:http://www.thescarms.com/dotnet/StackFrame.aspx

答案 3 :(得分:0)

我们这样做:

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

 DALayer.ExecuteProc("procName",dict);

ExecuteProc函数中,您可以迭代Dictionary对象并使用KeyValuePair对象设置参数。但是如果你必须为参数设置数据类型,长度等,那么你必须做更多的工作,比如准备sql命令来查询参数或传递更复杂的对象作为包含有关数据类型,长度和方向等信息的参数。