【问题标题】:Inheriting From a Generic List从通用列表继承
【发布时间】:2015-11-23 17:42:57
【问题描述】:

我觉得我应该知道这个问题的答案,但我不是 100% 如果这种方法能像我认为的那样奏效。如果我制作具有可覆盖列表的 Generic T Collection 类。如果我为通用列表制作了一堆新功能。使用通用添加、插入等覆盖列表的类是否允许其他不是所需对象的对象进入列表?我认为它不会允许它,但同时因为 Add 和 Insert 将允许任何对象传递到 T 集合中。那么假设我将列表覆盖为人类类型,添加方法是否允许将其他类型(如 cat)插入到该列表中?

[Serializable]
    private class List<T> : IList
    {
        private virtual IList<T> wrappedList;

        /// <summary>
        /// Create a non-generic IList wrapper
        /// around a generic IList&lt;T&gt; interface.
        /// </summary>
        /// <param name="wrappedList">The IList&lt;T&gt; interface to wrap.</param>
        public List(IList<T> wrappedList)
        {
            this.wrappedList = wrappedList;
        }

        /// <summary>
        /// Convert the given parameter to T. Throw an ArgumentException
        /// if it isn't.
        /// </summary>
        /// <param name="name">parameter name</param>
        /// <param name="value">parameter value</param>
        private static T ConvertToItemType(string name, object value)
        {
            try {
                return (T)value;
            }
            catch (InvalidCastException) {
                throw new ArgumentException(string.Format(Strings.WrongType, value, typeof(T)), name);
            }
        }


        public int Add(object value)
        {  
            // We assume that Add always adds to the end. Is this true?
            wrappedList.Add(ConvertToItemType("value", value));
            return wrappedList.Count - 1;
        }

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

        public bool Contains(object value)
        {
            if (value is T)
                return wrappedList.Contains((T)value);
            else
                return false;
        }

        public int IndexOf(object value)
        {
            if (value is T)
                return wrappedList.IndexOf((T)value);
            else
                return -1;
        }

        public void Insert(int index, object value)
        { wrappedList.Insert(index, ConvertToItemType("value", value)); }

        public bool IsFixedSize
        {
            get { return false; }
        }

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

        public void Remove(object value)
        {  
            if (value is T)
                wrappedList.Remove((T)value); 
        }   

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

        public object this[int index]
        {
            get { return wrappedList[index]; }
            set { wrappedList[index] = ConvertToItemType("value", value); }
        }

        public void CopyTo(Array array, int index)
        {
            if (array == null)
                throw new ArgumentNullException("array");

            int i = 0;
            int count = wrappedList.Count;

            if (index < 0)
                throw new ArgumentOutOfRangeException("index", index, Strings.ArgMustNotBeNegative);
            if (index >= array.Length || count > array.Length - index)
                throw new ArgumentException("index", Strings.ArrayTooSmall);

            foreach (T item in wrappedList) {
                if (i >= count)
                    break;

                array.SetValue(item, index);
                ++index;
                ++i;
            }
        }

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

        public bool IsSynchronized
        {
            get { return false; }
        }

        public object SyncRoot
        {
            get { return this; }
        }

        public IEnumerator GetEnumerator()
        {  return ((IEnumerable)wrappedList).GetEnumerator(); }
    }

这里是继承类

private class List<Human> : List<T>
{ 
     private override IList<Human> wrappedList 

}

如果我将项目添加到 List 是否允许我添加非人类项目,因为它的 add 方法是从 List 继承的。我不认为它会允许它,因为我说人类。这是我所期望的行为,但只是确保。

【问题讨论】:

  • 你将不得不展示你的代码。
  • 代码通常比叙述更容易理解,但听起来你在描述一个集合类,它可能继承一个泛型但也可能使用一个通用的存储集合,但实现了您提到的方法。 List&lt;T&gt; 有时继承是个坏主意,因为消费代码对排序和清除等内容有太多访问权限
  • @Plutonix 这样更有意义吗?
  • 你知道那不是 VB.NET 代码,对吧?看起来您还试图违反类型约束
  • 你不想为 List 写扩展吗?

标签: c# list


【解决方案1】:

也许你想要这个?

public static class ListExtensions
{
    public static void AddHuman(this IList<Human> list, Human item)
    {
         list.Add(item);
    }
}

并使用:

var list = new List<Human>();
list.AddHuman(new Human());

【讨论】:

    【解决方案2】:

    泛型对特定类型或接口(以及它的基类/基接口)进行操作。常用的“T”是创建实例时将存在于该对象上的类型占位符(将 T 替换为实际类型)。

    您的示例继承类实际上根本无法编译。类型推断仅在您创建实例或在类继承/接口实现链中指定它时起作用。你可以这样做:

    private class MyHumanList : List<Human> { }
    

    这与List&lt;Human&gt; 基本相同。

    “Cat”无法插入到这个列表中,因为泛型方法只允许“Human”对象插入其中,但这也取决于您定义的 Human 和 Cat 的继承关系。

    如果“Cat”可以成功转换为 Human(如果您已将“Human”定义为“Cat”的基类),则可以通过基类 List&lt;Human&gt; 公开的各种 Add/Insert 方法添加它目的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-03
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 2011-11-13
      相关资源
      最近更新 更多