动态对象 - 运行报告,现场没有present,但是可以看到它的调试器? [英] dynamic object - runtime reports field not present but can see it in debugger?

查看:111
本文介绍了动态对象 - 运行报告,现场没有present,但是可以看到它的调试器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:重新启动Visual Studio中没有code变更修复了这个问题


我有一个使用动态类型和在Expando对象ConfigSection处理程序。测试失败报告对象不包含SportName的定义。我曾在一个控制台采取ConfigSection处理的方程来进行复制,但看起来像相当于code正常工作。我很为难。

请参阅下面的测试,ConfigurationSectionHandler和配置XML

 公共类SportSection:IConfigurationSectionHandler
{
    公共对象创建(对象的父母,对象configContext,XmlNode的部分)
    {
        VAR DOC = XDocument.Parse(section.OuterXml);
        VAR根=(的XElement)doc.FirstNode;

        尝试
        {
            VAR sportList = root.Element(sportList)元素(运动)选择(ToSport)。

            动态配置=新ExpandoObject();
            config.SportList = sportList;

            返回的配置;
        }
        赶上(例外前)
        {
            抛出新ConfigurationErrorsException(无效SportSection配置,前);
        }
    }

    私有静态动态ToSport(的XElement sportElement)
    {
        尝试
        {
            VAR getAttrib =新的函数功能:LT;的XElement,字符串,字符串>((X,ATR)=> x.Attribute(ATR).value的);
            VAR getDictionary =
                新的函数功能:LT; IEnumerable的<的XElement>中的IDictionary<字符串,字符串>>(elems => elems.ToDictionary(X => x.Attribute(name)的值,Y => y.Attribute(值)。值));

            返回新
            {
                SportName = sportElement.Attribute(名)。价值,
                EventProperties = getDictionary(sportElement.Element(eventProperties)。元素(物业)),
                CompetitionProperties = getDictionary(sportElement.Element(competitionProperties)。元素(物业)),
                。MappedMarkets = sportElement.Element(映射)元素(市场)选择(X =>新MappedMarket(){类型= getAttrib(X型),MappedType = getAttrib(X,mappedType) })
            };
        }
        赶上(例外前)
        {

            抛出前;
        }

    }
}


[测试]
    公共无效GoodConfig()
    {
        VAR文件=新的XmlDocument();
        document.LoadXml(Resources.ValidSportSectionConfig);

        无功配置=新SportSection()创建(NULL,NULL,文件)动态。

        IEnumerable的<动态> sportList = config.SportList;

        Assert.AreEqual(1,sportList.Count());
        //Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:对象不包含SportName的定义
        Assert.AreEqual(棒球,sportList.Select(X =>(串)x.SportName)。首先());

        VAR eventProperties = sportList.First(X => x.SportName ==棒球)EventProperties为IDictionary的<字符串,字符串取代;

        Assert.AreEqual(2,eventProperties.Count);
        Assert.AreEqual(BSB,eventProperties [SportId]);
        Assert.AreEqual(THA,eventProperties [CompetitorReferenceId]);

        VAR compProps = sportList.First(X => x.SportName ==棒球)CompetitionProperties为IDictionary的<字符串,字符串取代;
        Assert.AreEqual(2,compProps.Count);
        Assert.AreEqual(BSB,compProps [SportId]);
        Assert.AreEqual(银联,compProps [CompetitionOrgMethodId]);

        变种mappedMarkets =(sportList.First(X => x.SportName ==棒球)MappedMarkets为IEnumerable&所述; MappedMarket&GT)了ToList()。
        Assert.AreEqual(2,mappedMarkets.Count());
        Assert.AreEqual(match_winner,mappedMarkets [0]。键入);
        Assert.AreEqual(BSBAO,mappedMarkets [0] .MappedType);
        Assert.AreEqual(障碍,mappedMarkets [0]。键入);
        Assert.AreEqual(BSBAQ,mappedMarkets [0] .MappedType);
    }

< sportSettings>
  < sportList>
    <运动NAME =棒球>
    < eventProperties>
      <属性名=SportId值=BSB>< /性>
      <属性名=CompetitorReferenceId值=THA>< /性>
    < / eventProperties>
    < competitionProperties>
      <属性名=SportId值=BSB/>
      <属性名=CompetitionOrgMethodId值=银联/>
    < / competitionProperties>
    <测绘>
      <市场型=match_winnermappedType =BSBAO/>
      <市场型=障碍mappedType =BSBAQ/>
    < /映射>
    < /运动>
  < / sportList>
< / sportSettings>
 

更新 - 堆栈跟踪:

 在CallSite.Target(封闭,调用点,对象)
在System.Dynamic.UpdateDelegates.UpdateAndExecute1 [T0,TRET](调用点的网站,T0为arg0)
在SS.Integration.EVenue.WindowsService.UnitTests.Configuration.SportSectionTests.<GoodConfig>b__11(Object X)在C:\_Git\SS.Integration.EVenue\SS.Integration.EVenue.WindowsService.UnitTests\Configuration\SportSectionTests.cs:line 35
 

解决方案

ToSport 返回一个匿名类型,而不是一个 ExpandoObject 。你当你施放匿名类型动态要小心,因为这些类型具有的访问修饰符内部。因此,如果你跨越程序集边界运行时将看不到任何accessable属性。尝试:

 私有静态动态ToSport(的XElement sportElement)
    {
        尝试
        {
            VAR getAttrib =新的函数功能:LT;的XElement,字符串,字符串&GT;((X,ATR)=&GT; x.Attribute(ATR).value的);
            VAR getDictionary =
                新的函数功能:LT; IEnumerable的&LT;的XElement&gt;中的IDictionary&LT;字符串,字符串&GT;&GT;(elems =&GT; elems.ToDictionary(X =&GT; x.Attribute(name)的值,Y =&GT; y.Attribute(值)。值));


            动态N =新ExpandoObject();
            。n.SportName = sportElement.Attribute(姓名)的价值;
            n.EventProperties = getDictionary(sportElement.Element(eventProperties)元素(房产));
            n.CompetitionProperties = getDictionary(sportElement.Element(competitionProperties)元素(房产));
            。n.MappedMarkets = sportElement.Element(映射)元素(市场)选择(X =&GT;新MappedMarket(){类型= getAttrib(X型),MappedType = getAttrib(X,mappedType )});

            返回N;
        }
        赶上(例外前)
        {

            抛出前;
        }

    }
 

EDIT : restarting visual studio fixed this issue with no code changes.


I have a ConfigSection handler that uses dynamic types and an expando object. The test fails reporting 'object' does not contain a definition for 'SportName'. I have tried to replicate in a console taking the ConfigSection handler out of the equation but what looks like the equivalent code works fine. I'm stumped.

See below for test, ConfigurationSectionHandler and config xml

public class SportSection : IConfigurationSectionHandler
{
    public object Create(object parent, object configContext, XmlNode section)
    {
        var doc = XDocument.Parse(section.OuterXml);
        var root = (XElement)doc.FirstNode;

        try
        {
            var sportList = root.Element("sportList").Elements("sport").Select(ToSport);

            dynamic config = new ExpandoObject();
            config.SportList = sportList;

            return config;
        }
        catch (Exception ex)
        {
            throw new ConfigurationErrorsException("Invalid SportSection configuration", ex);
        }
    }

    private static dynamic ToSport(XElement sportElement)
    {
        try
        {
            var getAttrib = new Func<XElement, string, string>((x, atr) => x.Attribute(atr).Value);
            var getDictionary =
                new Func<IEnumerable<XElement>, IDictionary<string, string>>(elems => elems.ToDictionary(x => x.Attribute("name").Value, y => y.Attribute("value").Value));

            return new
            {
                SportName = sportElement.Attribute("name").Value,
                EventProperties = getDictionary(sportElement.Element("eventProperties").Elements("property")),
                CompetitionProperties = getDictionary(sportElement.Element("competitionProperties").Elements("property")),
                MappedMarkets = sportElement.Element("mapping").Elements("market").Select(x => new MappedMarket() { Type = getAttrib(x, "type"), MappedType = getAttrib(x, "mappedType") })
            };
        }
        catch (Exception ex)
        {

            throw ex;
        }

    }
}


[Test]
    public void GoodConfig()
    {
        var document = new XmlDocument();
        document.LoadXml(Resources.ValidSportSectionConfig);

        var config = new SportSection().Create(null, null, document) as dynamic;

        IEnumerable<dynamic> sportList = config.SportList;

        Assert.AreEqual(1, sportList.Count());
        //Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : 'object' does not contain a definition for 'SportName'
        Assert.AreEqual("Baseball", sportList.Select(x => (string) x.SportName).First()); 

        var eventProperties = sportList.First(x => x.SportName == "Baseball").EventProperties as IDictionary<string, string>;

        Assert.AreEqual(2, eventProperties.Count);
        Assert.AreEqual("BSB", eventProperties["SportId"]);
        Assert.AreEqual("THA", eventProperties["CompetitorReferenceId"]);

        var compProps = sportList.First(x => x.SportName == "Baseball").CompetitionProperties as IDictionary<string, string>;
        Assert.AreEqual(2, compProps.Count);
        Assert.AreEqual("BSB", compProps["SportId"]);
        Assert.AreEqual("CUP", compProps["CompetitionOrgMethodId"]);

        var mappedMarkets = (sportList.First(x => x.SportName == "Baseball").MappedMarkets as IEnumerable<MappedMarket>).ToList();
        Assert.AreEqual(2, mappedMarkets.Count());
        Assert.AreEqual("match_winner" , mappedMarkets[0].Type);
        Assert.AreEqual("BSBAO", mappedMarkets[0].MappedType);
        Assert.AreEqual("handicap", mappedMarkets[0].Type);
        Assert.AreEqual("BSBAQ", mappedMarkets[0].MappedType);
    }

<sportSettings>
  <sportList>
    <sport name="Baseball">
    <eventProperties>
      <property name="SportId" value="BSB"></property>
      <property name="CompetitorReferenceId" value="THA"></property>
    </eventProperties>
    <competitionProperties>
      <property name="SportId" value="BSB" />
      <property name="CompetitionOrgMethodId" value="CUP" />
    </competitionProperties>
    <mapping>
      <market type="match_winner" mappedType="BSBAO" />
      <market type="handicap" mappedType="BSBAQ" />
    </mapping>
    </sport>
  </sportList>
</sportSettings>

UPDATE - Stack Trace:

at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at SS.Integration.EVenue.WindowsService.UnitTests.Configuration.SportSectionTests.<GoodConfig>b__11(Object x) in C:\_Git\SS.Integration.EVenue\SS.Integration.EVenue.WindowsService.UnitTests\Configuration\SportSectionTests.cs:line 35

解决方案

ToSport returns an anonymous type rather than an ExpandoObject. You have to be careful when you cast an anonymous type to dynamic, because those types have an access modifier of internal. Thus, if you cross assembly boundaries the runtime won't see any accessable properties. Try:

 private static dynamic ToSport(XElement sportElement)
    {
        try
        {
            var getAttrib = new Func<XElement, string, string>((x, atr) => x.Attribute(atr).Value);
            var getDictionary =
                new Func<IEnumerable<XElement>, IDictionary<string, string>>(elems => elems.ToDictionary(x => x.Attribute("name").Value, y => y.Attribute("value").Value));


            dynamic n = new ExpandoObject();
            n.SportName = sportElement.Attribute("name").Value;
            n.EventProperties = getDictionary(sportElement.Element("eventProperties").Elements("property"));
            n.CompetitionProperties = getDictionary(sportElement.Element("competitionProperties").Elements("property"));
            n.MappedMarkets = sportElement.Element("mapping").Elements("market").Select(x => new MappedMarket() { Type = getAttrib(x, "type"), MappedType = getAttrib(x, "mappedType") });

            return n;
        }
        catch (Exception ex)
        {

            throw ex;
        }

    }

这篇关于动态对象 - 运行报告,现场没有present,但是可以看到它的调试器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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