2009-02-10 101 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