Ошибка при использовании конструктора для универсального списка, который принимает коллекцию - PullRequest
0 голосов
/ 22 декабря 2009

Я пытался проанализировать XML с использованием интерфейса Fluent, как описано здесь .

Пример хорош, но выдает одну ошибку компилятора, которую я не могу исправить.

Ошибка в защищенном конструкторе ниже:

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 ------");
            }
        }
    }
}

Ответы [ 2 ]

3 голосов
/ 22 декабря 2009

Защищенный конструктор, который вы разместили в первом примере кода, отличается от того, который вы опубликовали во втором примере кода ...

Этот будет работать!

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

Этот не будет! (

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

Разница заключается в использовании скобок по сравнению с блоком инициализатора (не уверен, что это технический термин). Версия в скобках вызовет перегрузку универсального конструктора List, которая принимает универсальный IEnumerable в качестве параметра. Версия с фигурными скобками попытается добавить общий IEnumerable в качестве одного элемента в списке.

3 голосов
/ 22 декабря 2009
    protected DynamicXml(IEnumerable<XElement> iteratorElem)
    {
        _elements = new List<XElement> { iteratorElem };
    } 

- инициализатор последовательности. Это создаст список с одним элементом «iteratorElem», который не относится к типу XElement (как говорит ошибка).

Призвание:

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

должно работать, хотя. Вы также можете написать iteratorElem.ToList()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...