C#类工厂

时间:2011-03-14 22:11:46

标签: c# design-patterns

我有一个名为Foo的类,其函数类似于以下

List<Bar> LoadData();

Foo和Bar都在我想在其他项目中重用的库中。现在我正在开发一个新项目,我想继承Bar。我们称之为NewBar。

让Foo.LoadData返回NewBar列表的简单而灵活的方法是什么?我认为工厂是需要的,或者只是一个委托功能。任何人都可以提供一个例子吗?

谢谢,安迪

6 个答案:

答案 0 :(得分:3)

可能更简单,取决于你需要什么,但如果Bar是用无参数构造函数构造的,那么泛型约束就足够了:

public List<TBar> LoadData<TBar>()
    where TBar : Bar, new()
{
    // return a list populated with `new TBar()`;
}

用法:

var newBars = Foo.LoadData<NewBar>();

答案 1 :(得分:2)

最简单的方法是让Bar和NewBar实现一个接口,让函数返回List<IBar>

就是这样或者返回object并且施展嘉豪。

答案 2 :(得分:1)

LoadData()虚拟。然后在派生工厂中覆盖它。

如果派生的工厂方法仍会返回Bar的列表,但您可以在方法实现中指定所有Bar实例实际上都是NewBar。这可以通过使用像Snowbear的例子中的通用方法来改变。

答案 3 :(得分:1)

这里有一些问题。由于您使用的是List<Bar>,如果您返回List<Baz>,这将无效,因为List<>未执行协方差

我的建议是重新设计它以返回IEnumerable<Bar>并将其设为virtual,以便在新项目中创建SubFoo,然后您可以返回IEnumerable<Baz>


更新

好的,根据你提供的新信息(你用它来填充XML列表),我会创建一个virtual protected CreateBar()来创建一个新的bar对象并由LoadData调用()在循环中创建新的Bar。在SubFoo我覆盖并返回Baz。在SubFoo中,我将调用base.LoadData()并填充Baz列表,然后添加逻辑以填充Baz中不属于Bar的新属性。< / p>

或者

只需使用XML Serilization,我就可以免费获得所有这些内容!

答案 4 :(得分:0)

是时候了解协方差和逆变。学习并不是一件小事。基本上我建议创建一个IBar interfarce,它会让你的生活更轻松。

了解概念msdn,但您也应继续寻找其他示例。

答案 5 :(得分:0)

读完答案后(谢谢!)我想出了以下内容。为什么这不是个好主意?

public interface IBarFactory
{
    Bar Create();
}

然后将LoadData更改为:

List<Bar> LoadData(IBarFactory Factory)
{
    List<Bar> MyList = new List<Bar>();

    if (Factory == null)
    {
        MyList.Add(new Bar());
    }
    else
    {
        MyList.Add(Factory.Create());
    }

    // etc, etc
}

然后我只需要创建以下内容:

public class BazFactory : IBarFactory
{
    Bar Create() { return new Baz() };
}

最后称之为:

MyList = LoadData(BazFactory);