假设我们在.NET中创建一个通用控件,例如:一棵树。我不明白为什么人们使用这个通用类型定义。
Control<T>
在面向对象编程中,我可以使用抽象类或接口:
Control<IItem> or Control<BaseClass>
所以唯一需要做的就是,它们的类型必须派生自该基类或实现该接口。 这是否意味着泛型类型更方便,因为我不需要实现或继承任何内容?
假设我们在.NET中创建一个通用控件,例如:一棵树。我不明白为什么人们使用这个通用类型定义。
Control<T>
在面向对象编程中,我可以使用抽象类或接口:
Control<IItem> or Control<BaseClass>
所以唯一需要做的就是,它们的类型必须派生自该基类或实现该接口。 这是否意味着泛型类型更方便,因为我不需要实现或继承任何内容?
我觉得你可能有一点困惑。泛型和抽象类/接口在应用设计中各有不同的目标。抽象类/接口是为了将一组实体的共同功能进行概括。随后 API 可以以不同的方式进行实现,但由于涉及到多态性,因此不会影响任何人。
另一方面,有时你会有非常相似的某些实现,唯一的区别就是你所使用的对象类型。这时你就需要泛型。你可以使用多态性,但没有必要。为此,最清晰的方法就是定义一个接口,做出一个实现,让最终用户决定使用哪种类型的对象。
最好的例子就是 List,其中列表的主要目的是存储元素。列表实现者不应关心您将使用哪种类型的对象,因此稍后您将能够简单地定义 List 并使用整数列表。
因为在您的树形控件案例中,定义一个通用的树形控件意味着树形项目可以是任何类型(您还可以添加某些限制)。
在实例化控件时,您当然必须声明您的项目类型(就像在第二个代码示例中使用 IItem
和 BaseClass
一样)。
如果您的树形控件不是通用类型,那么您将不得不为每种项目类型创建几个控件。
为什么不只使用接口/抽象基类?
如果您只使用接口/抽象作为您的项目具体类,您将受到它的定义的约束。您只能看到它的属性和方法。使用通用树形控件和任何项目类型,您仍然能够访问所有项目的属性和方法,而不管其接口实现或父类继承...
where T : struct
),还是引用类型(where T : class
),或者它具有默认构造函数(where T : new()
)。 - Daniel Earwicker