2012-01-17 6 views
0
[TestFixture] 
public class ExpandoToMessageConverterTests 
{ 
/// <summary> 
/// CanConvertEvent 
/// </summary> 
[Test] 
public void CanConvertEvent() 
{ 
    dynamic expandoEvent = new ExpandoObject(); 
    expandoEvent.PropertyOne = "pROPERTYoNE"; 
    expandoEvent.PropertyTow = "pROPERTYtWO"; 

    XElement xEvent=ExpandoToMessageConverter.ExpandoToMessageEvent(expandoEvent); 

    /*var xEvent = new XElement("event", 
           new XElement("properties", 
              new XElement("property", 
                 new XAttribute("name", "pROPERTYoNE"), 
                 new XAttribute("value", "someVal")), 
              new XElement("property", 
                 new XAttribute("name", "pROPERTYtWO"), 
                 new XAttribute("value", "BLAH"))));*/ 
    Assert.IsNotNull(xEvent); 
    var properties = new List<XElement>(xEvent.Descendants("properties")); 
    Assert.AreEqual(1,properties.Count); 


    var value = ((IEnumerable)xEvent.XPathEvaluate("properties/property")).Cast<XElement>(); 
    Assert.AreEqual(2, value.Count()); 
} 

上記のコードでは、同じxmlをさまざまな方法で作成しています(1つは明示的にコメントアウトされています)。もう1つは、XElementを返すExpandoToMessageEvent(ExpandoObject)を使用しています。ここ は、私にとっては謎です:ダイナミックオーバーロード解決で拡張メソッド候補が考慮されないのはなぜですか?

  • 私はCLRがXPathEvaluateはXElementオブジェクトに定義されていないと文句を言いたXEvent VARとするXEventを宣言した場合。確かにそうではありません。その拡張メソッド。
  • スニペットの現在の動作(つまり、xEventはXElementとして宣言されています)、正常に動作します。
  • 「動的」で始まり、現在コメントアウトされているセクションをExpandoToMessageEventメソッドの呼び出しの最後に置き換えた場合、CLRは満足しています。

明らかに、私はそれを動作させることができます。しかし、問題は:なぜ動的な言葉がCLRをスローするのでしょうか?

私は新しいExpandoObject()を関数に渡し、次に "var xEvent = ExpandoToMessageConverter.ExpandoToMessageEvent(new ExpandoObject())"のxEventの型を渡すと、 "が正しく決定され、CLRは満足しています。しかし、 "dynamic blah = new ExpandoObject()"と "var xEvent = ExpandoToMessageEvent(blah)"と言うと、xEventの型は正しくはわかりません(CLRはXElementの拡張メソッドを考慮していないようです)。

+0

ExpandoToMessageEventメソッドのシグニチャはどのように見えますか? – Groo

+0

... ExpandoToMessageEvent(ExpandoObject)、XElementを返します...そのポストで... – AlexeiOst

答えて

9

動的呼び出しのオーバーロード解決では、拡張メソッドは考慮されません。

特定のコールで使用できる拡張機能の方法を決定するには、コールサイトで「使用中」のディレクティブが有効であったことが必要です。この情報をコールサイトに保存するための既存のメカニズムはありませんでした。私たちは新しいメカニズムを設計、実装、テスト、文書化する予算を持っておらず、C#4を期限通りに出荷していました。したがって、この機能の一部を削除しました。

+0

xEventはExpandoObjectではありません。もっと慎重に読んでください。 – AlexeiOst

+1

@AlexeiOstですが、 'var'を使うと' dynamic'として扱われます。実際のタイプは関係ありません。 'ExpandoToMessageEven()'の呼び出しは動的なので、 'dynamic'を返します。 – svick

+0

私は今理解しています。ありがとう、エリック、ありがとう、スヴィク。 – AlexeiOst

2

varを使用しているため、コンパイラのように見えて拡張メソッドを推測できませんでした。エラーが発生しました。ただし、dynamicは、動的変数がコンパイル時の型チェック(reference)を受けないため、正常に動作します。

+0

しかし、拡張メソッドは、通常、パラメータが指定されている場合には戻り値の型を推測する必要がありますか? – Groo

+0

パラメータはそれとは関係ありません。 – AlexeiOst

+0

そして、Li0liQ:それは奇妙な部分です。あなたが言うことは、間違いなく明らかです。私はいくつかの事を確認することにしました。ここに私が見つけたものがあります:新しいExpandoObject()を関数に渡すと、 "var xEvent = ExpandoToMessageConverter.ExpandoToMessageEvent(new ExpandoObject())"のxEventの型が正しく決定されますCLRは満足しています。しかし、 "dynamic blah = new ExpandoObject()"と "var xEvent = ExpandoToMessageEvent(blah)"と言うと、xEventの型は正しくはわかりません(CLRはXElementの拡張メソッドを考慮していないようです)。 – AlexeiOst

関連する問題