只接受几种类型的列表

时间:2012-03-29 14:18:27

标签: c# .net data-structures

C#容器中是否存在任何System命名空间,只能接受某些类型? 例如,我想创建我的列表,其中我只有类型为Class1和int的对象:

//accept only type Class1 and int;
MYLIST lst = new MYLIST(typeof(Class1), typeof(int));
lst.Add( 23 ); // OK
lst.Add( new Class1() ); // OK
lst.Add( "text" ); // wrong, not accepted type

在.NET中是这样的,还是我必须自己编写?感谢。

5 个答案:

答案 0 :(得分:3)

C#类型系统不允许您表达“Class1int”之类的内容。话虽如此,你可以使用重载来获得一半:

class MyClass
{
    private List<object> _items = new List<object>();
    public void Add(int value) { _items.Add(value); }
    public void Add(Class1 value) { _items.Add(value); }
    ...
}

真正棘手的问题是如何将事情 out ,而不是如何将放在中。有几种可能性:将所有内容都设为object(通过实施IEnumerable<object>),以及GetInt(int index)GetClass1(int index)等特殊方法。

答案 1 :(得分:1)

你无法直接实现这一目标。 List<T>的项类型必须是要添加到列表中的所有类型共有的基本类型。

您可以在List<object>原因周围找到List<object>或包装器。但是,您必须在运行时检查添加到其中的项目是否为正确的类型,并且您必须将从列表中检索的项目转换为正确的类型。

如果要在同一列表中存储不同的类型,一个好的选择是创建一个所有这些类型必须实现的接口

public interface ICommonInterface
{
    int Number { get; }
    string Text { get; }
}

public Class1 : ICommonInterface
{
    public int Number { get; set; }
    public string Text { get; set; }

    public string AnAdditionalProperty { get; set; }
}

public NumberWrapper : ICommonInterface
{
    public NumberWrapper (int number)
    {
        this.Number = number;
        this.Text = number.ToString();
    }

    public int Number { get; private set; }
    public string Text { get; private set; }
}

public TextWrapper : ICommonInterface
{
    public TextWrapper (string text)
    {
        this.Text = text;
        int i;
        Int32.TryParse(text, out i);
        this.Number = i;
    }

    public int Number { get; private set; }
    public string Text { get; private set; }
}

然后您可以将列表声明为

List<ICommonInterface> lst = new List<ICommonInterface>();
lst.Add(new Class1());
lst.Add(new NumberWrapper(77));
lst.Add(new TextWrapper("hello"));

Console.WriteLine(lst[0].Text);

答案 2 :(得分:1)

没有。你必须创建自己的。您可以实现ICollection或IEnumerable或IList或其他。你在这里有很多灵活性。但最重要的是,答案是否定的,不存在允许您自动将集合中的类型限制为某些类型的集合。

答案 3 :(得分:1)

答案是否定的,C#中没有这样的列表,并且非常好。

你可以制作一个包装器,但我建议反对它。

 public class CustomListWrapper< T, F>
    {
        private readonly List<object> internalList;
        public CustomListWrapper()
        {
            this.internalList = new List<object>();
        }

        public void Add(object item)
        {
            if(!(item is T || item is F))
                throw new Exception();

            this.Add(item);
        }

    }
PS:在downvote之前,关于如何让对象出来......这就是为什么这是一个相当糟糕的想法,但是你必须在你能够获得的类型上做一个“是”将其转换为合适的类型。

同样,不完全确定为什么你需要这样做。

答案 4 :(得分:0)

为什么不包装List&lt;&gt;,并制作两个add方法,一个接受int,另一个接受Class1