抛出泛型列表和CollectionDataContract之间的问题

时间:2011-06-03 10:11:44

标签: c# wcf type-conversion datacontractserializer

我定义了以下收集合同:

[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。这是可能的,还是通过派生一个新对象,我创建了一种不会以这种方式工作的新类型的列表。

我目前解决此问题的方法是声明一个新的Center实例,并使用foreach将所有中心复制到其中。

3 个答案:

答案 0 :(得分:1)

问题是Centres&#34;是&#34; 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>.

进行隐式转换

答案 1 :(得分:1)

你在尝试什么不会工作。

如果可能的话,你应该考虑重构中心到 List<Centre> 关系,或者至少定义一个{{1}的构造函数}}

这样你就可以写:

IEnumerable<Centre>

当然,这一切都取决于您的具体情况,这可能不是一个有效的解决方案。

答案 2 :(得分:0)

您可以做的是创建自己的包装IList的IList<T>接口实现。 它需要更多代码,但不会像复制所有对象一样慢:

  [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
    }