2009-12-22 2 views
0

here과 같이 Fluent 인터페이스를 사용하여 XML을 구문 분석하려고했습니다.컬렉션을 사용하는 일반 목록에 생성자를 사용할 때의 오류

예제가 좋지만 수정할 수없는 컴파일러 오류가 하나 있습니다.

이 오류는 아래 보호 생성자 인 :이 라인에서 얻을

protected DynamicXml(IEnumerable<XElement> elements) 
{ 
    _elements = new List<XElement>(elements); // error on this line 
} 

두 개의 컴파일러 오류입니다 :

Argument 1: cannot convert from 
'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' to 
'System.Xml.Linq.XElement' 

The best overloaded Add method  
'System.Collections.Generic.List<System.Xml.Linq.XElement>. 
Add(System.Xml.Linq.XElement)' for the collection initializer 
has some invalid arguments 

내가 가지고있는 복사/아래의 전체 코드를 붙여 넣었습니다 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Dynamic; 
using System.Xml.Linq; 
using System.Collections; 

namespace FluentXML 
{ 
    public class DynamicXml : DynamicObject, IEnumerable 
    { 
     private readonly List<XElement> _elements; 

     public DynamicXml(string text) 
     { 
      var doc = XDocument.Parse(text); 
      _elements = new List<XElement> { doc.Root }; 
     } 

     protected DynamicXml(XElement element) 
     { 
      _elements = new List<XElement> { element }; 
     } 

     protected DynamicXml(IEnumerable<XElement> iteratorElem) 
     { 
      _elements = new List<XElement> { iteratorElem }; 
     } 

     public override bool TryGetMember(GetMemberBinder binder, out object result) 
     { 
      result = null; 
      if (binder.Name == "Value") 
       result = _elements[0].Value; 
      else if (binder.Name == "Count") 
       result = _elements.Count; 
      else 
      { 
       var attr = _elements[0].Attribute(
        XName.Get(binder.Name)); 
       if (attr != null) 
        result = attr; 
       else 
       { 
        var items = _elements.Descendants(
         XName.Get(binder.Name)); 
        if (items == null || items.Count() == 0) 
         return false; 
        result = new DynamicXml(items); 
       } 
      } 
      return true; 
     } 

     public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) 
     { 
      int ndx = (int)indexes[0]; 
      result = new DynamicXml(_elements[ndx]); 
      return true; 
     } 

     public IEnumerator GetEnumerator() 
     { 
      foreach (var element in _elements) 
       yield return new DynamicXml(element); 
     } 
    } 
} 

namespace FluentXML 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string xmlString = FluentXML.Properties.Resources.InputString; 
      dynamic dx = new DynamicXml(xmlString); 
      Console.WriteLine("PublicationDate='{0}'", dx.pubdate.Value); 
      Console.WriteLine("BookCount='{0}'", dx.book.Count); 
      foreach (dynamic d in dx.book) 
      { 
       Console.WriteLine("----- Begin Book -----"); 
       Console.WriteLine("Price='{0}'", d.price.Value); 
       Console.WriteLine("Title='{0}'", d.title.Value); 
       Console.WriteLine("AuthorCount='{0}'", d.authors.author.Count); 
       foreach (dynamic a in d.authors.author) 
       { 
        Console.WriteLine(" ---- Begin Author ----"); 
        Console.WriteLine(" EmailAddress='{0}'", a.email.address.Value); 
        Console.WriteLine(" FirstName='{0}'", a.name.first.Value); 
        Console.WriteLine(" MiddleName='{0}'", a.name.middle.Value); 
        Console.WriteLine(" LastName='{0}'", a.name.last.Value); 
        Console.WriteLine(" ----- End Author -----"); 
       } 
       Console.WriteLine("------ End Book ------"); 
      } 
     } 
    } 
} 
+0

제목이 약간 혼란 스럽습니다. 귀하의 질문이 동적 프로그래밍과 관련이 있다고 생각하지 않습니까? – Niki

+0

예치 혼란 스럽습니다. 더 많은 의견을 얻기 위해 바꿔야합니다. – ardsrk

+0

"C# 프로그래밍 문제"도 너무 일반적입니다. –

답변

3
protected DynamicXml(IEnumerable<XElement> iteratorElem) 
    { 
     _elements = new List<XElement> { iteratorElem }; 
    } 

은 시퀀스 이니셜 라이저입니다. 이렇게하면 XElement 유형이 아닌 하나의 요소 "iteratorElem"이있는 목록이 작성됩니다 (오류가 나타내는대로).

콜링 :

protected DynamicXml(IEnumerable<XElement> iteratorElem) 
    { 
     _elements = new List<XElement>(iteratorElem); 
    } 

하지만, 작동합니다. 또한

이 하나가 작동합니다 ... iteratorElem.ToList()

3

첫 번째 코드 샘플에 게시 보호 된 생성자는 두 번째 코드 샘플에 게시 된 것과 동일하지 않습니다 쓸 수 있습니다!

protected DynamicXml(IEnumerable<XElement> elements) 
{ 
    _elements = new List<XElement>(elements); // error on this line 
} 

:(

protected DynamicXml(IEnumerable<XElement> iteratorElem) 
{ 
    _elements = new List<XElement> { iteratorElem }; 
} 

의 차이는 초기화 블록 (즉, 기술적 인 용어입니다 있는지 확실하지 않습니다) 대 괄호를 사용입니다. 괄호 버전은 매개 변수로 제네릭 IEnumerable을 소요 일반 목록 생성자 오버로드를 호출합니다. 중괄호가있는 버전은 일반 IEnumerable을 목록의 단일 요소로 추가하려고 시도합니다.

관련 문제