locked
IEnumerable<XElement> RRS feed

  • Question

  • Hi,

    I am calling a method to read the configuration file and the method returns IEnumerable<XElement>, and i have set a breakpoint in the method. When i debug it does not hit the breakpoint.

     public IEnumerable<XElement> ReadFile(string configFilePath)
            {
                using (var reader = XmlReader.Create(configFilePath))
                {
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element && reader.Name == "Name")
                        {
                            var e = XElement.ReadFrom(reader) as XElement;
                            yield return e;

                        }
                    }
                    reader.Close();
                }
            }

    and i call this method from a different class like

    objReadAppConfigFile.ReadFile(SystemStrings.configFilePath); without mentioning any explicit return type.

     

    Please tell me where i am going wrong


    litu Here
    Wednesday, August 24, 2011 11:43 AM

Answers

  • @Muthu, that is not entirely true, but it is true that the iterator will only be called the first time the value is actually requested. Until then it's just an instance of IEnumerable waiting to be enumerated.

    You should be able to assign it to a variable of type IEnumerable<T> (in this case T: XElement).

    You can iterate through it yourself by calling MoveNext() and then getting the Current property. This is what foreach does under the covers

    var items = objReadAppConfigFile.ReadFile(SystemStrings.configFilePath();
    
    while (items.MoveNext())
    {
       var item = items.Current;
       string value = item.Value;
       string name = item.Name;
    } 


    Until you call MoveNext, nothing actually happens. 

    By using

    foreach (var item in objReadAppConfigFile.ReadFile(SystemStrings.configFilePath())
    
    {
       string value = item.Value;
       string name = item.Name;
    }
    


    you will force the runtime to iterate through all the items. It will use the MoveNext()
    method and  Current property implicitly.


    • Edited by Jesse HouwingMVP Wednesday, August 24, 2011 9:57 PM markup
    • Proposed as answer by Alan_chen Thursday, August 25, 2011 1:04 PM
    • Marked as answer by Alan_chen Monday, August 29, 2011 12:27 PM
    Wednesday, August 24, 2011 9:53 PM

All replies

  • Hi,

    I am calling a method to read the configuration file and the method returns IEnumerable<XElement>, and i have set a breakpoint in the method. When i debug it does not hit the breakpoint.

     public IEnumerable<XElement> ReadFile(string configFilePath)
            {
                using (var reader = XmlReader.Create(configFilePath))
                {
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element && reader.Name == "Name")
                        {
                            var e = XElement.ReadFrom(reader) as XElement;
                            yield return e;

                        }
                    }
                    reader.Close();
                }
            }

    and i call this method from a different class like

    objReadAppConfigFile.ReadFile(SystemStrings.configFilePath); without mentioning any explicit return type.

     

    Please tell me where i am going wrong


    litu Here
    • Merged by Liliane Teng Monday, August 29, 2011 9:28 AM double post
    Wednesday, August 24, 2011 10:19 AM
  • that's not a vb question. try the c# forum:

     

    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/threads


    thanks for any help
    Wednesday, August 24, 2011 11:40 AM
  • Hi,

    I am calling a method to read the configuration file and the method returns IEnumerable<XElement>, and i have set a breakpoint in the method. When i debug it does not hit the breakpoint.

     public IEnumerable<XElement> ReadFile(string configFilePath)
            {
                using (var reader = XmlReader.Create(configFilePath))
                {
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element && reader.Name == "Name")
                        {
                            var e = XElement.ReadFrom(reader) as XElement;
                            yield return e;

                        }
                    }
                    reader.Close();
                }
            }

    and i call this method from a different class like

    objReadAppConfigFile.ReadFile(SystemStrings.configFilePath); without mentioning any explicit return type.

     

    Please tell me where i am going wrong


    litu Here
    litu Here
    • Merged by Alan_chen Thursday, August 25, 2011 1:06 PM duplicate
    Wednesday, August 24, 2011 11:51 AM
  • As long as you don't have an concrete use-case for using XmlReader and yield return, I would use the simpler XDocument:

     public IEnumerable<XElement> ReadFile(string configFilePath)
    {
      XDocument document = XDocument.Load(configFilePath);
      return document.Descendants("Name");
    }
    • Proposed as answer by aiw-nvs Thursday, August 25, 2011 2:58 AM
    Wednesday, August 24, 2011 11:54 AM
  • Are you testing this with

     

    foreach(XElement x in objReadAppConfigFile.ReadFile(SystemStrings.configFilePath))
    

     

     


    Muthu Krishnan.R Use only what you need, Reduce global warming
    Wednesday, August 24, 2011 11:59 AM
  • Hi,

    I call the method using this piece of line :--->   objReadAppConfigFile.ReadFile(SystemStrings.configFilePath);

    but the ReadFile method is not called.

    so, am i doing wrong somewhere

     


    litu Here
    Wednesday, August 24, 2011 12:03 PM
  • Hi ,

    foreach(XElement x in objReadAppConfigFile.ReadFile(SystemStrings.configFilePath))
    {}
    This piece of code is working, but please explain me the logic behind writing like this

     

     

     


    litu Here
    Wednesday, August 24, 2011 12:08 PM
    • Edited by Stefan Hoffmann Wednesday, August 24, 2011 12:13 PM broken link
    Wednesday, August 24, 2011 12:12 PM
  • Actually yield only works with foreach

    please refer http://msdn.microsoft.com/en-us/library/dscyy5s0(v=vs.80).aspx


    Muthu Krishnan.R Use only what you need, Reduce global warming
    Wednesday, August 24, 2011 12:14 PM
  • This is expected behavior when using yield return.  Your code will not execute until you iterate through the resulting IEnumerable from the method call. 


    Tom Overton
    Wednesday, August 24, 2011 12:27 PM
  • @Muthu, that is not entirely true, but it is true that the iterator will only be called the first time the value is actually requested. Until then it's just an instance of IEnumerable waiting to be enumerated.

    You should be able to assign it to a variable of type IEnumerable<T> (in this case T: XElement).

    You can iterate through it yourself by calling MoveNext() and then getting the Current property. This is what foreach does under the covers

    var items = objReadAppConfigFile.ReadFile(SystemStrings.configFilePath();
    
    while (items.MoveNext())
    {
       var item = items.Current;
       string value = item.Value;
       string name = item.Name;
    } 


    Until you call MoveNext, nothing actually happens. 

    By using

    foreach (var item in objReadAppConfigFile.ReadFile(SystemStrings.configFilePath())
    
    {
       string value = item.Value;
       string name = item.Name;
    }
    


    you will force the runtime to iterate through all the items. It will use the MoveNext()
    method and  Current property implicitly.


    • Edited by Jesse HouwingMVP Wednesday, August 24, 2011 9:57 PM markup
    • Proposed as answer by Alan_chen Thursday, August 25, 2011 1:04 PM
    • Marked as answer by Alan_chen Monday, August 29, 2011 12:27 PM
    Wednesday, August 24, 2011 9:53 PM
  • Thanks Jesse Houwing. Thats good update.


    Muthu Krishnan.R Use only what you need, Reduce global warming
    Thursday, August 25, 2011 2:25 AM