Проблемы приведения между общим списком и CollectionDataContract - PullRequest
1 голос
/ 03 июня 2011

У меня определен следующий коллекторский договор:

[CollectionDataContract(Name = "Centres")]
public class Centres : List<Centre>
{}

и следующий контракт операции, определенный для возврата этой коллекции

public Model.Centres GetCentres()
{
     List<Centre> allCentres = (from c in Model.Centre.GetCentres()
                                    where c.Visible == true
                                    select c).ToList();

     return allCentres
}

Но когда я запускаю код, я получаю ExplicitCastException. Итак, насколько я вижу, я пытаюсь вложить список центров (List) в мою коллекцию 'Centers', которая сама по себе происходит из List. Возможно ли это или путем получения нового объекта я создаю новый тип списка, который не будет работать таким образом.

Моя текущая работа по решению этой проблемы - объявить новый экземпляр центров и скопировать в него все центры, используя foreach.

Ответы [ 3 ]

1 голос
/ 03 июня 2011

То, что вы пытаетесь, не сработает.

Если возможно, вы должны рассмотреть возможность рефакторинга Центров, чтобы имел List<Centre> больше, чем , это отношение или, по крайней мере,определите конструктор, который принимает IEnumerable<Centre>

Таким образом, вы могли бы написать:

Centres allCentres = new Centres(from c in Model.Centres.GetCentres()
                                   where c.Visible == true
                                   select c);

Конечно, все зависит от вашей конкретной ситуации, когда это может быть неверным решением..

1 голос
/ 03 июня 2011

Проблема в Centres "это" List<Centre>, List<Centre> это не Centres.

Несмотря на то, что Centres не имеет реализации, он все еще является подклассом List<Centre>, вы можете расширить свой класс Centres, чтобы иметь оператор неявного преобразования, или, возможно, добавить конструктор для центров, который принимает List<Centre> в качестве параметра.

Попробуйте изменить Centres на что-то вроде ...

[CollectionDataContract(Name = "Centres")] 
public class Centres : List<Centre> 
{
    public static implicit operator Centres(List<Centre> l)
    {
        Centres newCentres = new Centres();
        newCentres.AddRange(l);
        return newCentres;
    }
}

Тогда это позволит неявное преобразование из List<Centre>.

0 голосов
/ 03 июня 2011

Что вы можете сделать, это создать собственную реализацию интерфейса IList<T>, который обертывает IList. Требуется больше кода, но не все так медленно, как копирование всех объектов:

  [CollectionDataContract(Name = "Centres")]
  public class Centres : IList<Centre>
    {
        private IList<Centre> _inner;
        private IList<Centre> Inner
        {
            get
            {
                if (_inner == null)
                    _inner = new List<Centre>();
                return _inner;
            }
        }
        public Centres(List<Centre> items)
        {
            _inner = items;
        }

        #region IList<Centre> Members

        public int IndexOf(Centre item)
        {
            return Inner.IndexOf(item);
        }

        public void Insert(int index, Centre item)
        {
            Inner.Insert(index, item);
        }

        public void RemoveAt(int index)
        {
            Inner.RemoveAt(index);
        }

        public Centre this[int index]
        {
            get
            {
                return Inner[index];
            }
            set
            {
                Inner[index] = value;
            }
        }

        #endregion

        #region ICollection<Centre> Members

        public void Add(Centre item)
        {
            Inner.Add(item);
        }

        public void Clear()
        {
            Inner.Clear();
        }

        public bool Contains(Centre item)
        {
            return Inner.Contains(item);
        }

        public void CopyTo(Centre[] array, int arrayIndex)
        {
            Inner.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return Inner.Count; }
        }

        public bool IsReadOnly
        {
            get { return Inner.IsReadOnly; }
        }

        public bool Remove(Centre item)
        {
            return Inner.Remove(item);
        }

        #endregion

        #region IEnumerable<Centre> Members

        public IEnumerator<Centre> GetEnumerator()
        {
            return Inner.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return Inner.GetEnumerator();
        }

        #endregion
    }
...