只接受少数类型的列表

本文关键字:类型 列表 | 更新日期: 2023-09-27 18:29:19

C#中的任何系统命名空间中是否存在只能接受某些类型的容器?例如,我想创建一个列表,其中只有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中有类似的东西吗?还是我必须自己写?谢谢

只接受少数类型的列表

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

真正棘手的问题是如何将的东西输出,而不是如何将的东西放入。有几种可能性:将所有内容都作为object(通过实现IEnumerable<object>),可能还有GetInt(int index)GetClass1(int index)等特殊方法。

答案是否定的,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);
        }
    }

附言:在否决之前,关于如何把物体拿出来。。。这就是为什么这是一个相当糟糕的主意,但你必须对你得到的类型做一个"is",才能将其转换为正确的类型。

再说一遍,不确定你为什么需要这样做。

否。你必须自己创造。您可以实现ICollection或IEnumerable或IList或其他任何东西。你在这里有很大的灵活性。但归根结底,答案是否定的,不存在允许您自动将集合中的类型限制为某些类型的集合。

您无法直接实现这一点。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);

为什么不包装一个List<>,并生成两个add方法,一个接受int,另一个接受Class1