【问题标题】:"Combined Type" - Generics - something else?“组合类型” - 泛型 - 别的?
【发布时间】:2014-04-23 11:01:07
【问题描述】:

我感觉自己失去了 OO 知识。实际上,问题看起来很简单:我想创建一个对对象进行操作的类

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

同时。

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

但是在这里不起作用:我们的大部分Forms都继承自OurCompanyForm,不需要实现IDescribedActionsProvider,我们的一些forms也没有继承,但是当它们实现接口时,它们应该是一个可接受的参数。 这里需要的是组合,而不是继承

然后我想到了泛型。我可以像这样定义我的班级

public class FormController<T> : IDisposable where T : Form, IDescribedActionsProvider
{
T _ControlledForm;
OtherType _OtherObject;

internal FormController(OtherType otherObject, T controlledForm)
{
    _OtherObject = otherObject;
    _ControlledForm = controlledForm;
    ....
}

它会按照我的预期工作,但感觉完全错误: 这不是泛型(参见 MSDN http://msdn.microsoft.com/en-us/library/sz6zd40f%28v=vs.100%29.aspx)的目的。 当我想在工厂中创建 FormController 对象时遇到问题(因为在那里创建了 OtherType ),它不是通用的,即像这样的函数 public FormController CreateFormcontroller(T受控表单) 是不可能的,因为 T 没有在这里定义......并且使用“SpecialForm”而不是 T 不起作用,因为组合与继承。

你有什么建议? “Duck Typing”——但这也不是一个好的 OO 实践?

编辑:

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

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

但我仍然对在这种情况下使用泛型表示怀疑:T 受控表单参数是单个对象,在 FormController 类中只有一个“类型”的实例,具体类型无关紧要 -这显然不同于例如一个列表。我并不“需要”一个 FormController 对象,只需要一个 FormController(恰好在那个表单上工作)。

【问题讨论】:

  • 我认为这没有任何问题。你有什么问题?
  • "我们的一些表单并没有继承自那里,但是当它们实现接口时,它们应该是一个可接受的参数" 为什么不直接接受一个IDescribedActionsProvider 对象作为参数呢?
  • 可以这样定义工厂方法:public FormController&lt;T&gt; CreateFormController&lt;T&gt;(T controlledForm) where T: Form, IDescribedActionsProvider
  • 另外,OtherType 在实践中是什么?它在 FormController 中的作用是什么,保证通过构造函数传递?

标签: c# oop generics


【解决方案1】:

“当我想在工厂中创建 FormController 对象时遇到问题(因为在那里创建了 OtherType),它不是通用的,即像 public 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;
    }
}

【讨论】:

  • 你是对的,可以这样。看起来我在尝试时弄错了那么多T。
【解决方案2】:

看起来并非您要控制的每个表单都是 IDescribedActionsProvider 类型。就不能做两个方法吗?:

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

【讨论】:

  • 对不起,这不正确:FormController 订阅了受控Form 的Form 事件,并调用了IDescribedActionsProvider 的方法。因此对象必须是两者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多