【发布时间】:2015-06-04 11:22:12
【问题描述】:
我有一个通用类,它处理可以从字符串反序列化的小部件。泛型类的实例将这些小部件之一的类型作为模板参数,然后从字符串创建这些小部件。我希望使用 C# 泛型的协方差属性来编写像WidgetUser<IWidget> 这样的代码来处理可能是WidgetUser<RedWidget> 或WidgetUser<BlueWidget> 的对象。问题是,要从WidgetUser<T> 中的字符串创建小部件,我不得不添加new() 作为保护。这使得WidgetUser<IWidget> 成为无效类型。目前,我有这样的代码:
interface IWidget
{
// Makes this widget into a copy of the serializedWidget
void Deserialize(string serializedWidget);
}
class WidgetUser<T> where T : IWidget, new()
{
public void MakeAndUse(string serializedWidget)
{
var widget = new T();
widget.Deserialize(serializedWidget);
Use(widget);
}
}
使用这段代码,我可以使WidgetUser<BlueWidget> 很好,因为BigWidget 满足new()。我不能写WidgetUser<IWidget>,因为IWidget(或等效抽象类)的实例不能保证与new()一起工作。解决方法可能是这样的:
abstract class WidgetUser
{
public abstract void MakeAndUse();
}
class WidgetUser<T> : WidgetUser
where T : IWidget, new()
{
/* same as before but with an 'override' on MakeAndUse */
}
使用这段代码,我可以创建一个WidgetUser<BlueWidget>,然后编写只处理WidgetUser 的代码。我可以使用抽象类BaseWidget 而不是IWidget 来完成类似的代码,它完成几乎相同的事情。这是功能性的,但我怀疑有一种更直接的方法不会强迫我定义一个虚拟类。如何在不创建虚拟类或额外工厂的情况下将我的意图传达给类型系统。我只想要一个界面,上面写着“您可以从字符串中制作其中一个”。
TL;DR:
有没有办法编写一个接口或抽象类,让我可以从字符串创建一个实例,但不需要我将new() 作为WidgetUser<T> 的保护?
【问题讨论】:
-
because instances of IWidget are not guaranteed to work with new()为什么?是因为new()必须有一个公共的无参数构造函数吗?如果是这样,请使用class代替您的Constraints on Type Parameter。 -
您要么需要以某种方式提供工厂对象,要么需要使用
new()约束。为什么你不能简单地扭转你的问题并说小部件类必须有一个无参数的构造函数来与你的小部件用户一起工作? -
如何为小部件指定接口或抽象基类以保证无参数构造函数?
-
目前我不明白你的摘要
MakeAndUse有什么问题,所以我不知道。 -
because instances of IWidget are not guaranteed to work with new()为什么?
标签: c# oop generics interface abstract-class