2009-02-10 99 views
1

寻找一种将关联数组传递给方法的方法。我正在寻找重写在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); 

,并找出一些方法来使用,在补间功能(我不知道如何在关键分开=值的给该对象。任何想法?)

c)中创建一个Dictionary<string, object>的参数传递到吐温功能

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

编辑

我花了一整天都摸不着头脑:

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

回答

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

这使您既易用性和易用性消费的 - “丑陋”反映的东西是在一个构造函数包裹起来的字典,而不是你的方法。而且,当然,字典可以反复使用,只用一次写入反射代码。

1

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

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

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

而且声明是沿着线的东西:

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

的想法是,你可以采取可变数目的“这回对象的功能”。然后分析每个参数的名称Expression<TDelegate>,并调用每个参数以获取其值。

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

更新

其实我已经写了传递关联数组作为我的博客上,herehere字典的念头。

+0

这是一个有趣的想法。它似乎有点滥用(看到你定义的“功能”实际上除了传递你的硬编码数据外实际上没有做任何事情),但它很整洁。 – mquander 2009-02-10 01:54:39

+0

是的,我更喜欢匿名类型。 – 2009-02-10 01:59:04

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#方式这样做是为每个可能的参数创建一个真实的TweenParameters结构或类,然后创建一个传递给tween()。这通常被认为是更易于维护的,因为所有“可用”属性对于调用者来说都是显而易见的,而无需查看tween()的内部,并且因为它在编译时捕获错误,直到运行时字符串比较才会注意到打字“持续时间”“duratoin”。

+0

我确实喜欢在结构中维护可用参数列表的“正确”列表。 – typeoneerror 2009-02-10 03:55:41