将关联数组传递给方法的简明方法

时间:2009-02-10 01:36:25

标签: c# silverlight associative-array parameter-passing

寻找将关联数组传递给方法的方法。我想在C#中重写一个Actionscript补间包,但遇到“关联”数组/对象的问题。通常在Actionscript中我可能会这样做:

public function tween(obj:DisplayObject, params:Object = null):void {
    if (params.ease != null) {
        //do something
    }
    //...
}

这可以称为:

tween(this, {ease:'out', duration:15});

我正在寻找一种在C#中做同样事情的方法。到目前为止,我已经选择了:

a)创建一个类或结构来定义可能的param键和类型并传递

b)将参数作为泛型类型传递

tween(frameworkElement, new {ease = 'out', duration = 15});

假设

public static void tween(FrameworkElement target, object parameters);

并找出在补间函数中使用它的一些方法(我不知道如何分离key = value给定的那个对象。任何想法?)

c)创建Dictionary<string, object>以将参数传递到补间函数

任何其他想法或示例代码?我是C#的新手。

修改

让我整天想出这个:

“不能跨程序集边界共享匿名类型。编译器确保每个程序集中给定的属性名称/类型对序列最多只有一个匿名类型。要在程序集之间传递结构,您需要正确定义它们。“

3 个答案:

答案 0 :(得分:1)

我喜欢选项(b)我自己 - 传递匿名类型并使用反射解析出值。

我见过其他人使用lambda表达式实现相同的功能。调用语法为:

tween(frameworkElement, ease => "out", duration => 15);

宣言将有以下几点:

public static void tween(FrameworkElement target, params Expression<Func<object>>[] parameters) { ... }

这个想法是你可以使用可变数量的“返回对象的函数”。然后,您解析每个Expression<TDelegate>中的参数名称,并调用每个参数以获取其值。

我认为这不比反映匿名类型好,但这是另一种需要考虑的方法。

<强>更新

我实际上已经写过关于在我的博客herehere上将关联数组作为字典传递的想法。

答案 1 :(得分:1)

字典是一种合理的方法。它可能看起来像这样:

public static void tween(FrameworkElement target, IDictionary<string, object> parameters)
{
    if (parameters.ContainsKey("ease")) {
        //do something
    }
}

请注意,当您传入值时,可以使用缩短的集合初始化语法使其更容易,例如:

tween(something, new Dictionary<string, object> { { "ease", "out" }, { duration, 15 } });

与ActionScript代码大致相同,这是一种非常快速的方法,但它并不是很好的C#。 C#-ish的方法是创建一个真实的TweenParameters结构或类,其中包含每个可能参数的属性,然后创建一个传递给tween()。这通常被认为是更易于维护的,因为所有“可用”属性对调用者来说都是显而易见的,而不需要查看tween()的内部结构,并且因为它在编译时捕获错误,直到运行时才会发现字符串比较,如错字“持续时间”“duratoin”。

答案 2 :(得分:1)

编辑:这基本上是HtmlHelper扩展在ASP.NET MVC中使用的机制。这不是我的原创。


我赞成采用两种不同签名的混合方法。注意:我没有尝试过这个,两个签名之间可能存在冲突,因此您可能必须给第二个方法稍微不同的名称,以允许编译器在它们之间进行选择,但我不这么认为。

public static void tween( FrameworkElement target, object parameters )
{
    return tween( target, new ParameterDictionary( parameters ) );
}

public static void tween( FrameworkElement target,
                          ParameterDictionary values )
{
    if (values.ContainsKey( "ease" ))
    {
      ....
    }
}

然后你有一个ParameterDictionary类,它使用匿名类型的反射并设置字典。

public class ParameterDictionary : Dictionary<string,object>
{
    public ParameterDictionary( object parameters )
    {
         if (parameters != null)
         {
             foreach (PropertyInfo info in parameters.GetType()
                                                     .GetProperties())
             {
                 object value = info.GetValue(parameters,null);
                 this.Add(info.Name,value);
             }
         }
    }
}

这使您既易于使用又易于使用 - “丑陋”的反射内容包含在字典的单个构造函数中,而不是在您的方法中。当然,字典可以一次又一次地用于类似目的,反射代码只写一次。