如果我们使用的所有类通常都是从一些普通类继承的,那么为什么我们需要泛型?

Feo*_*akt 0 c# generics inheritance

美好的一天.泛型通常使用如下:

class MyList<T>
{
    public T data;
    public MyList<T> nextElement;
}
Run Code Online (Sandbox Code Playgroud)

为什么不使用以下:

class MyList
{
    public object data;
    public MyList nextElement;
}
Run Code Online (Sandbox Code Playgroud)

甚至:

class MyStructure<T> where T : SomeCommonClass
{
    public T data;
    public MyStructure<T> nextElement;
    public MyStructure<T> prevElement;
}
Run Code Online (Sandbox Code Playgroud)

而是:

class MyStructure
{
    public SomeCommonClass data;
    public MyStructure nextElement;
    public MyStructure prevElement;
}
Run Code Online (Sandbox Code Playgroud)

更新:

好吧,我担心你没有完全理解我,甚至降低了我的问题.没有泛型的示例,它正常工作:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

        MyNode nodeButton = new MyNode("nodeButton", new Button());
        MyNode nodeTextBox = new MyNode("nodeTextBox", new TextBox());
        MyNode nodeCheckBox = new MyNode("nodeCheckBox", new CheckBox());
        MyList myList = new MyList() { nodeButton, nodeTextBox, nodeCheckBox };
        for (int i = 0; i < myList.Count;i++)
        {
            this.Controls.Add(myList[i].Data);
            myList[i].Data.Left = 100 * i;
        }
    }
}

public class MyNode
{
    public MyNode(string name, Control data)
    {
        Data = data;
        Name = name;
    }
    public string Name { get; private set; }
    public Control Data { get; private set; }
}

public class MyList : Collection<MyNode>
{
    protected override void InsertItem(int index, MyNode item)
    {
        base.InsertItem(index, item);
        item.Data.MouseClick += new MouseEventHandler((sender, e) => { MessageBox.Show(item.Name); });
    }
}
Run Code Online (Sandbox Code Playgroud)

与泛型一样的例子,在编译时会产生错误:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

        MyNode<Button> nodeButton = new MyNode<Button>("nodeButton", new Button());
        MyNode<TextBox> nodeTextBox = new MyNode<TextBox>("nodeTextBox", new TextBox());
        MyNode<CheckBox> nodeCheckBox = new MyNode<CheckBox>("nodeCheckBox", new CheckBox());
        MyList myList = new MyList() { (MyNode<Control>)nodeButton, (MyNode<Control>)nodeTextBox, (MyNode<Control>)nodeCheckBox };
        for (int i = 0; i < myList.Count;i++)
        {
            this.Controls.Add(myList[i].Data);
            myList[i].Data.Left = 100 * i;
        }
    }
}

public class MyNode<T> where T : Control
{
    public MyNode(string name, T data)
    {
        Data = data;
        Name = name;
    }
    public string Name { get; private set; }
    public T Data { get; private set; }
}

public class MyList : Collection<MyNode<Control>>
{
    protected override void InsertItem(int index, MyNode<Control> item)
    {
        base.InsertItem(index, item);
        item.Data.MouseClick += new MouseEventHandler((sender, e) => { MessageBox.Show(item.Name); });
    }
}
Run Code Online (Sandbox Code Playgroud)

据你说,第一个版本是不好的做法,因为类型安全被打破,但第二个版本不允许类型转换!

Ry-*_*Ry- 9

在这两种情况下,您都可能丢失很多关于对象的信息,并且有很多类型的安全性.铸造不愉快.您也无法确保列表包含特定类型的对象.

使用值类型时,性能也会显着下降; 他们必须装箱和装箱object,这很慢,而且不安全.

事实上,你建议做的(嗯,仍然存在)!它被称为ArrayList并且非常可怕.