";“组合型”-Generics——其他的东西

本文关键字:组合型 其他 quot -Generics | 更新日期: 2023-09-27 17:59:39

我感觉失去了OO知识。事实上,问题看起来很简单:我想创建一个类,它对

  • 从System.Windows.Forms.Form继承
  • 实现接口IDescriptiondActionsProvider

同时。

我可以创建一个新的表单类型公共抽象类SpecialForm:Form,IDescriptiondActionsProvider并且需要该SpecialForm类型的参数。

但它在这里不起作用:我们的大多数表单继承自OurCompanyForm,这些表单不需要实现IDescriptiondActionsProvider,我们的一些表单也不从那里继承,但当它们实现接口时,它们应该是一个可接受的参数。这里需要的是组合,而不是继承

然后我想到了Generics。我可以像一样定义我的类

public class FormController<T> : IDisposable where T : Form, IDescribedActionsProvider
{
T _ControlledForm;
OtherType _OtherObject;
internal FormController(OtherType otherObject, T controlledForm)
{
    _OtherObject = otherObject;
    _ControlledForm = controlledForm;
    ....
}

它会按照我的意图工作,但感觉完全错误:Generics并非如此(请参阅MSDNhttp://msdn.microsoft.com/en-us/library/sz6zd40f%28v=vs.100%29.aspx)是为之设计的。当我想在工厂中创建FormController对象(因为在那里创建了OtherType)时,我会遇到问题,它不是通用的,即类似public FormController CreateFormcontroller(T controlled Form)不可能,因为这里没有定义T。。。使用"SpecialForm"代替T是不起作用的,因为组合与继承。

你有什么建议?"鸭子打字"——但这也不是一个好的OO练习?

编辑:

要传递给FormController的对象必须是这两种类型,因为它向Form的事件进行描述,并调用接口的方法。

Boris B.的评论和Weyland Yutani的回答中描述的在工厂方法中定义T是有效的。

但我仍然对泛型在这种情况下的使用持怀疑态度:T controlled Form参数是一个单独的对象,FormController类中只有该"类型"的一个实例,具体的类型没有任何意义——这显然与List<int>。我不"需要"FormController对象,只需要一个FormController(恰好在该表单上工作)。

";“组合型”-Generics——其他的东西

"当我想在一个非通用的工厂中创建FormController对象时(因为在那里创建了OtherType),我会遇到问题,即像公共FormController CreateFormcontroller(T controlledForm)这样的函数是不可能的,因为这里没有定义T…"

我可能搞错了,但你不能在工厂方法上定义t吗?

class Factory
{
    public static FormController<T> CreateFormController<T>(T controlledForm) where T : Form, IDescribedActionsProvider
    {
        return new FormController<T>(new OtherType(), controlledForm);
    }
}
class FormController<T> where T : Form, IDescribedActionsProvider
{
    T _ControlledForm;
    internal FormController(OtherType otherObject, T controlledForm)
    {
        _ControlledForm = controlledForm;
    }
}

看起来并不是每个要控制的Form都是IDescriptiondActionsProvider类型。你就不能做两种方法吗

abstract class FormController
{
    abstract void Handle(IDescribedActionsProvider form);
    abstract void Handle(Form form);
}