寻找将关联数组传递给方法的方法。我想在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#的新手。
修改
让我整天想出这个:
“不能跨程序集边界共享匿名类型。编译器确保每个程序集中给定的属性名称/类型对序列最多只有一个匿名类型。要在程序集之间传递结构,您需要正确定义它们。“
答案 0 :(得分:1)
我喜欢选项(b)我自己 - 传递匿名类型并使用反射解析出值。
我见过其他人使用lambda表达式实现相同的功能。调用语法为:
tween(frameworkElement, ease => "out", duration => 15);
宣言将有以下几点:
public static void tween(FrameworkElement target, params Expression<Func<object>>[] parameters) { ... }
这个想法是你可以使用可变数量的“返回对象的函数”。然后,您解析每个Expression<TDelegate>中的参数名称,并调用每个参数以获取其值。
我认为这不比反映匿名类型好,但这是另一种需要考虑的方法。
<强>更新强>
答案 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);
}
}
}
}
这使您既易于使用又易于使用 - “丑陋”的反射内容包含在字典的单个构造函数中,而不是在您的方法中。当然,字典可以一次又一次地用于类似目的,反射代码只写一次。