为什么动态重载分辨率不考虑扩展方法候选? [英] Why does dynamic overload resolution not consider extension method candidates?

查看:160
本文介绍了为什么动态重载分辨率不考虑扩展方法候选?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  [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名称,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(一个,显式的,被注释掉)。另一个是使用ExpandoToMessageEvent(ExpandoObject),它返回一个XElement。
这是我的谜:




  • 如果我将xEvent声明为var xEvent,则CLR抱怨XElement中未定义XPathEvaluate 。实际上不是它的一个扩展方法。

  • 现在的代码片段(即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的扩展方法。

解决方案

动态调用的重载解析不考虑扩展方法。



<确定在给定呼叫中可用的扩展方法需要知道呼叫站点上使用了哪些使用指令。我们以前没有将这些信息持续到通话网站的机制;我们没有预算来设计,实施,测试和记录新的机制,并且仍然按时运送C#4。因此,我们剪掉了这部分功能。


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

In the code above I create the same xml in different ways (one, explicit, is commented out). The other one is using the ExpandoToMessageEvent(ExpandoObject), which returns a XElement. Here is the mystery for me:

  • if I declare xEvent as var xEvent the CLR complains that XPathEvaluate is not defined on XElement. It is not, indeed; its an extension method.
  • the way the snippet is now (i.e. xEvent declared as XElement), it works fine.
  • if I replace the section starting with 'dynamic' and ending at the end of the call to my ExpandoToMessageEvent method with the section that is currently commented out CLR is happy.

Obviously, I can make it work. But the question is: why does 'dynamic' word throw CLR off?

I decided to check a couple more things and here is what I found: If i pass a new ExpandoObject() to the function then the type of xEvent in the "var xEvent = ExpandoToMessageConverter.ExpandoToMessageEvent(new ExpandoObject())" is determined correctly and CLR is happy. However, if I say "dynamic blah = new ExpandoObject()" and then " var xEvent=ExpandoToMessageEvent(blah)", the type of xEvent is not determined correctly (I guess) and CLR does not seem to consider extension methods for XElement.

解决方案

Overload resolution of a dynamic invocations does not consider extension methods.

Determining what extension methods are available on a given call requires knowing what "using" directives were in force at the call site. We had no previously existing mechanism for persisting this information into the call site; we did not have the budget to design, implement, test and document a new mechanism and still ship C# 4 on time. We therefore cut that portion of the feature.

这篇关于为什么动态重载分辨率不考虑扩展方法候选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆