传递API的许多参数

时间:2014-12-11 19:57:40

标签: c# dictionary argument-passing

我有一个执行复杂数学分析的API。分析目前涉及12个不同组件值的计算,但组件值的数量是可变的:它将改变(可能增加)。将添加组件,某些组件可能会被删除。每个组件都需要指定许多参数(每个组件的编号不同)。需要设置所有参数值以便进行分析。

API通过两种方法调用,每种方法都有一个重载。

方法1:AnaylyzeAll()

此方法利用所有已知组件进行分析,并对所有组件参数使用默认值。

方法1重载:AnaylyzeAll(componentParameters)

此方法利用所有已知组件进行分析,并使用用户指定的值覆盖指定组件的select参数的默认值。

方法2:AnaylyzeSelect(componentsToBeAnalyzed)

此方法使用为分析指定的组件,并使用所有组件参数的默认值。

方法2重载:AnaylyzeSelect(componentsToBeAnalyzed,componentParameters)

此方法使用为分析指定的组件,并使用用户值作为指定组件的select参数的参数。

componentsToBeAnalyzed是一个用户初始化列表,如下所示:

internal readonly List<string> componentsToBeAnalyzed = new List<string>()
{
    "ComponentB",
    "ComponentG",
    "ComponentA"
};

我正在考虑使用ReadOnlyCollection,但由于我的目标是.Net 3.5,这可能会增加复杂性。

componentParameters对象对我来说是个问题。我需要允许用户指定为其提供参数的组件以及参数值。我作为解决方案提出的是使用一个匿名类型数组,然后我将其转换为一个列表,然后我将其转换为嵌套字典。

用户提供以下内容,

var componentParameters = new []
{
    new { ComponentName = "ComponentA", ParameterName = "Parameter 1", paramValue = (object)3.247 },
    new { ComponentName = "ComponentA", ParameterName = "Parameter 3", paramValue = (object)"volatile" },
    new { ComponentName = "ComponentA", ParameterName = "Parameter 7", paramValue = (object)Method.Standard },

    new { ComponentName = "ComponentC", ParameterName = "Parameter 2", paramValue = (object)11 },
    new { ComponentName = "ComponentC", ParameterName = "Parameter 5", paramValue = (object)1.145 }
};

在API中,我按如下方式处理

var componentInfo = componentParameters.ToList();
Dictionary<string, Dictionary<string, object>> dict2 = componentInfo
    .GroupBy(x => x.ComponentName)
    .ToDictionary(gComponentName => gComponentName.Key,
                  gComponentName => gComponentName.ToDictionary(t => t.ParameterName,
                                                                t => t.paramValue));

我的问题是,这对我来说看起来不是干净优雅的代码。我一直试图弄清楚如何将其重构为更简单,更有效但却无法实现的目标。我还想简化用户如何输入参数值。我想要像

这样的东西
var componentParameters2 = new object []
{
    new { name = "ComponentA", param1=3.247, param3 = "volatile", param7 = Method.Standard },
    new { name = "ComponentC", param2 = 11, param5 =1.145 }
};

但是我无法将其转换为与上面相同类型的嵌套字典。如何最好地处理这种情况的任何建议和建议将不胜感激。

1 个答案:

答案 0 :(得分:0)

如果您要创建一个代表您的参数的类,例如:

,该怎么办?
public class Component
{
    public string Name { get; set; }

    public Dictionary<string, object> Parameters { get; set; }

    public object this[string key]
    {
        get
        {
            return this.Parameters[key];
        }
        set
        {
            if(this.Parameters.ContainsKey(key))
            {
                this.Parameters[key] = value;
            }
            else
            {
                this.Parameters.Add(key, value);
            }
        }
    }
}

然后您就可以使用它:

var components = new Component
    {
        Name = "ComponentA"
    };

components["parameter1"] = 123;
components["parameter2"] = "volatile";
components["parameter3"] = Method.Standard;

// etc...

也许这有帮助?

要解决希望简洁的语法问题,请尝试在构造函数中使用params关键字。

public Component(string name, params KeyValuePair<string, object>[] parameters)
{
    Name = name;

    Parameters = new Dictionary<string, object>(parameters);
}

这将允许以下初始化语法:

var components = new []
    {
        new Component("ComponentA", new []
            {
                { "Parameter1", 123 },
                { "Parameter2", "volatile" },
                { "Parameter3", Method.Standard },
            },
        new Component("ComponentB", new []
            {
                { "Parameter5", 12.25 },
                { "Parameter7", 12 }
            },
    };